From 35c2a569b53d26c68cd0b1bf04dbec1fcdbc1a64 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 11 May 2021 10:04:32 +0200 Subject: [PATCH 1/3] MOBILE-3746 a11y: Highlight focused element --- .../mod/forum/components/index/index.html | 2 +- src/core/components/combobox/combobox.scss | 25 +++++++++++-------- .../tabs-outlet/core-tabs-outlet.html | 1 + src/theme/theme.base.scss | 15 +++++++++++ src/theme/theme.light.scss | 1 + 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/addons/mod/forum/components/index/index.html b/src/addons/mod/forum/components/index/index.html index c66bb6cf4..e79488e3d 100644 --- a/src/addons/mod/forum/components/index/index.html +++ b/src/addons/mod/forum/components/index/index.html @@ -86,7 +86,7 @@ + (click)="discussions.select(discussion)" button>

diff --git a/src/core/components/combobox/combobox.scss b/src/core/components/combobox/combobox.scss index 19a8eb6fc..7f9ce62d1 100644 --- a/src/core/components/combobox/combobox.scss +++ b/src/core/components/combobox/combobox.scss @@ -19,19 +19,19 @@ --padding-end: 10px; --padding-bottom: 10px; --padding-start: 16px; + + &.md { + --background-activated-opacity: 0; + --background-focused-opacity: .12; + } + + &.ios { + --background-activated-opacity: .12; + --background-focused-opacity: .15; + } } } -:host-context(.md) { - --background-activated-opacity: 0; - --background-focused-opacity: .12; -} - -:host-context(.ios) { - --background-activated-opacity: .12; - --background-focused-opacity: .15; -} - ion-select, ion-button { background: var(--background); @@ -42,6 +42,11 @@ ion-button { overflow: hidden; margin: 8px; box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12); + + &:focus, + &:focus-within { + border: 2px solid var(--a11y-focus-outline-color); + } } ion-select { diff --git a/src/core/components/tabs-outlet/core-tabs-outlet.html b/src/core/components/tabs-outlet/core-tabs-outlet.html index 4662bb224..c6963585f 100644 --- a/src/core/components/tabs-outlet/core-tabs-outlet.html +++ b/src/core/components/tabs-outlet/core-tabs-outlet.html @@ -14,6 +14,7 @@ [hidden]="!hideUntil" [id]="tab.id! + '-tab'" class="tab-slide" + tabindex="-1" [class.selected]="selected == tab.id"> Date: Wed, 12 May 2021 11:52:19 +0200 Subject: [PATCH 2/3] MOBILE-3746 format-text: Convert show more to ion-button --- src/core/directives/format-text.ts | 18 +++++++++--------- src/theme/components/format-text.scss | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/directives/format-text.ts b/src/core/directives/format-text.ts index 0b1e0c388..6faa75a06 100644 --- a/src/core/directives/format-text.ts +++ b/src/core/directives/format-text.ts @@ -256,14 +256,17 @@ export class CoreFormatTextDirective implements OnChanges { */ protected displayShowMore(): void { const expandInFullview = CoreUtils.isTrueOrOne(this.fullOnClick) || false; - const showMoreDiv = document.createElement('div'); + const showMoreButton = document.createElement('ion-button'); - showMoreDiv.classList.add('core-show-more'); - showMoreDiv.innerHTML = Translate.instant('core.showmore'); - this.element.appendChild(showMoreDiv); + showMoreButton.classList.add('core-show-more'); + showMoreButton.setAttribute('fill', 'clear'); + showMoreButton.innerHTML = Translate.instant('core.showmore'); + this.element.appendChild(showMoreButton); if (expandInFullview) { this.element.classList.add('core-expand-in-fullview'); + } else { + showMoreButton.setAttribute('aria-expanded', 'false'); } this.element.classList.add('core-text-formatted'); this.element.classList.add('core-shortened'); @@ -624,11 +627,8 @@ export class CoreFormatTextDirective implements OnChanges { * "Hide" the "Show more" in the element if it's shown. */ protected hideShowMore(): void { - const showMoreDiv = this.element.querySelector('div.core-show-more'); - - if (showMoreDiv) { - showMoreDiv.remove(); - } + const showMoreButton = this.element.querySelector('ion-button.core-show-more'); + showMoreButton?.remove(); this.element.classList.remove('core-expand-in-fullview'); this.element.classList.remove('core-text-formatted'); diff --git a/src/theme/components/format-text.scss b/src/theme/components/format-text.scss index 31c6554ca..e453640a6 100644 --- a/src/theme/components/format-text.scss +++ b/src/theme/components/format-text.scss @@ -38,6 +38,7 @@ core-format-text { min-height: 50px; .core-show-more { + text-transform: none; text-align: end; font-size: 14px; display: block; @@ -45,7 +46,7 @@ core-format-text { @include position(null, 0, 0, null); z-index: 7; background-color: var(--background); - color: var(--color); + color: var(--text-color); padding-left: 10px; // RTL } @@ -68,7 +69,7 @@ core-format-text { &.core-expand-in-fullview { .core-show-more { @include push-arrow-color(626262, true); - @include padding-horizontal(null, 18px); + @include padding-horizontal(null, 5px); @include background-position(end, 0, center); background-repeat: no-repeat; From e2d96e2de2895d338afe3855cd1dd2fa8483cf3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 13 May 2021 16:39:16 +0200 Subject: [PATCH 3/3] MOBILE-3746 a11y: Improve focus styles --- src/core/components/combobox/combobox.scss | 2 +- src/theme/globals.mixins.scss | 19 +++++++++++ src/theme/theme.base.scss | 37 ++++++++++++++++++++-- src/theme/theme.light.scss | 3 +- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/core/components/combobox/combobox.scss b/src/core/components/combobox/combobox.scss index 7f9ce62d1..cffe1c11a 100644 --- a/src/core/components/combobox/combobox.scss +++ b/src/core/components/combobox/combobox.scss @@ -45,7 +45,7 @@ ion-button { &:focus, &:focus-within { - border: 2px solid var(--a11y-focus-outline-color); + @include core-focus-style(); } } diff --git a/src/theme/globals.mixins.scss b/src/theme/globals.mixins.scss index de13c44eb..28049c24b 100644 --- a/src/theme/globals.mixins.scss +++ b/src/theme/globals.mixins.scss @@ -4,6 +4,25 @@ * Place here our custom mixins. */ + @mixin core-focus() { + outline: none; + position: relative; + &::after { + @include position(0, 0, 0, 0); + position: absolute; + content: ""; + opacity: 1; + z-index: 1; + @include core-focus-style(); + } + } + + @mixin core-focus-style() { + box-shadow: inset 0 0 var(--a11y-focus-width) 1px var(--a11y-focus-color); + // Thicker option: + // border: var(--a11y-focus-width) solid var(--a11y-focus-color); +} + @mixin core-transition($where: all, $time: 500ms) { -webkit-transition: $where $time ease-in-out; -moz-transition: $where $time ease-in-out; diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss index 06514e2f4..1a40d75f4 100644 --- a/src/theme/theme.base.scss +++ b/src/theme/theme.base.scss @@ -502,16 +502,47 @@ audio.core-media-adapt-width { } // Focus highlight for accessibility. +ion-item.item-input.ion-focused:not(:focus), .ion-focused, +ion-item.ion-activatable.ion-focused:not(:focus), ion-input.has-focus, .ion-focused ion-toggle:focus-within, .ion-focused ion-select:focus-within, .ion-focused ion-checkbox:focus-within, .ion-focused ion-radio:focus-within { - border: 2px solid var(--a11y-focus-outline-color); + @include core-focus(); } // Treat cases where there's a focusable element inside an item, like a button. -ion-item.ion-focused:not(:focus) { - border: none; +ion-item.ion-focused:not(:focus), +ion-item.item-input ion-input.has-focus { + position: relative; + &::after { + box-shadow: revert; + opacity: revert; + z-index: revert; + } + .item-highlight, .item-inner-highlight { + position: unset; + } +} + +// Change default outline. +:focus-visible { + @include core-focus-style(); + outline: none; +} + +textarea, button, select, input, a { + &:focus { + @include core-focus-style(); + outline: none; + } +} + +ion-input .native-input{ + &:focus, &:focus-visible { + box-shadow: none; + outline: none; + } } diff --git a/src/theme/theme.light.scss b/src/theme/theme.light.scss index 6e0560c88..f9f1e91fd 100644 --- a/src/theme/theme.light.scss +++ b/src/theme/theme.light.scss @@ -64,7 +64,8 @@ // Accessibility vars. --a11y-min-target-size: 44px; - --a11y-focus-outline-color: #005ECC; + --a11y-focus-color: var(--primary); + --a11y-focus-width: 2px; --module-icon-size: 24px;