Создавайте более доступные приложения Angular

1. Прежде чем начать

черный угловой логотип

Доступность — жизненно важная часть веб-разработки, гарантирующая, что пользователи могут воспринимать, понимать, перемещаться и взаимодействовать с приложениями. Фактически, каждый четвертый взрослый в США имеет инвалидность, которая влияет на его основную жизнедеятельность. Во всем мире около 15 процентов населения планеты (более 1 миллиарда человек) имеют ту или иную форму инвалидности, при этом от 2 до 4 процентов испытывают значительные трудности.

К распространенным состояниям, влияющим на использование Интернета человеком, относятся слепота или слабое зрение, глухота или нарушение слуха, ограниченные двигательные навыки, когнитивные нарушения и дальтонизм — и это лишь неполный список.

В этом курсе a11y означает доступность. Обратите внимание, что за a следуют 11 символов и y .

Подробную информацию о проблемах и методах разработки доступных приложений см. в разделе «Доступность» .

Что ты построишь

  • Используйте лучшие практики и встроенные методы для решения распространенных проблем с доступностью в Интернете в демонстрационном приложении Dumpling Shop Angular.
  • Соблюдайте все рекомендации по доступности, WCAG 2.0 и ARIA 1.2, а также пройдите проверки доступности Axe и Lighthouse.

Сайт магазина Dumpling Time в розово-красной тематикеСайт магазина Dumpling Time в фиолетово-зеленой теме

Что вы узнаете

Вы узнаете о восьми распространенных проблемах доступности в приложениях Angular, которые затрагивают пользователей, о том, как их идентифицировать и как их исправить. Точнее, вы:

  • Используйте инструменты разработчика Google Chrome, Lighthouse и ax для проверки доступности вашего приложения.
  • Устранение ошибок одностраничных приложений (SPA) с помощью уникальных заголовков страниц
  • Исправление проблем с низким цветовым контрастом для пользователей со слабым зрением.
  • Используйте семантический HTML, чтобы программы чтения с экрана правильно перемещались по странице.
  • Используйте Angular Material и отключите элементы управления, чтобы программы чтения с экрана могли получить доступ ко всем элементам управления.
  • Добавьте поддержку ARIA для программ чтения с экрана.
  • Импортируйте и используйте пакет Angular CDK a11y.
  • Используйте FocusTrap для навигации по средствам чтения с экрана пользовательских компонентов.
  • Объявляйте уведомления с помощью CDK LiveAnnouncer
  • Обнаруживайте пользователей с помощью режима HighContrast и реализуйте высококонтрастные темы.

Что вам понадобится

2. Настройте

Получить код

Все, что вам нужно для этого проекта, находится в репозитории GitHub. Для начала клонируйте код и откройте его в любимой среде разработки.

Клонируйте репозиторий и обслуживайте приложение

VSCode или локальная IDE — рекомендуемый метод для работы с этой лабораторией кода.

  1. Откройте новую вкладку браузера и перейдите по адресу https://github.com/googlecodelabs/angular-accessibility .
  2. Разветвите и клонируйте репозиторий и cd angular-accessibility/ в репозиторий.
  3. Ознакомьтесь с веткой стартового кода git checkout get-started .
  4. Откройте код в VSCode или предпочитаемой вами IDE.
  5. Запустите npm install , чтобы установить зависимости, необходимые для запуска сервера.
  6. Запустите ng serve , чтобы запустить сервер.
  7. Откройте вкладку браузера по адресу http://localhost:4200 .

3. Установите базовый уровень

Какова ваша отправная точка?

Ваша отправная точка — базовое ресторанное приложение, разработанное для этой лаборатории кода. Код был упрощен, чтобы показать концепции этой лаборатории кода, и у него мало функций.

Сайт магазина Dumpling Time в фиолетово-зеленой теме

Изучите демо-версию

Для начала ознакомьтесь с тремя функциями вашего приложения:

  1. Используйте панель навигации, чтобы просмотреть маршруты «Наш магазин» , «Наша история» и «Найти нас» , а также узнать подробную информацию о компании, производящей пельмени.
  2. Измените темы, чтобы переключить светлый и темный режим.
  3. Настройте начинку, количество и цвет пельменей вашего заказа.
  4. Выберите «Купить» , чтобы зарегистрировать свой индивидуальный заказ в консоли.

Используйте Angular для решения распространенных проблем с доступностью в Интернете.

В этой лаборатории вы сосредоточитесь на доступности существующих функций этого приложения. Вы начнете с выявления всех проблем в своем приложении, а затем превратите 🛑 в ✅, внедрив решение.

Откуда вы знаете, что исправить?

Начинайте каждый пример с выявления проблемы доступности, используя сочетание ручного и автоматического тестирования.

В нынешнем состоянии Интернета проверка доступности вручную является обязательной.

У вас есть инструменты, которые могут выявить проблемы с доступностью, но ни один инструмент не может подтвердить, что приложение полностью доступно. Ручное тестирование гарантирует, что вы проверите широкий спектр концепций, включая логический порядок контента и четность функций.

Ручное тестирование

Чтобы вручную проверить специальные возможности в этом курсе, вы включаете встроенную в наш компьютер программу чтения с экрана и перемещаетесь по приложению с помощью клавиатуры. Дополнительные сведения см. в разделе Семантика и программы чтения с экрана .

Потренируйтесь, включив программу чтения с экрана и перемещаясь по экрану.

Вы можете использовать встроенную в MacOS функцию VoiceOver. Нажмите «Системные настройки» > «Универсальный доступ » > VoiceOver > «Включить VoiceOver», чтобы включить его . Чтобы переключить VoiceOver, быстро нажмите TouchID три раза, удерживая клавишу Command .

В этом курсе вы в основном тестируете проблемы вручную и используете автоматизированные инструменты для проверки определенных автоматизированных функций.

Автоматизированное тестирование

Вы также используете несколько инструментов разработки для автоматизации и аудита вашего приложения. Эти инструменты позволяют вам проверять такие вещи, как наличие замещающего текста на изображении или коэффициент контрастности цвета текста. Вы можете думать об этих инструментах как о линтерах; они могут распознать наличие замещающего текста, но вы должны вручную проверить, что содержимое логично и имеет ценность.

Инструменты разработчика Lighthouse и Chrome

  1. Откройте Инструменты разработчика Chrome.
  2. Выберите вкладку «Маяк» и установите флажок «Доступность» .
  3. Нажмите «Создать отчет» , чтобы запустить аудит a11y Lighthouse.

Вкладка «Пример маяка» с кнопкой «Создать отчет» на вкладке «Инструменты разработчика Chrome»

Топор

  1. Установите расширение axe DevTools . Возможно, вам придется перезапустить браузер, чтобы увидеть расширение.
  2. Откройте Инструменты разработчика Chrome.
  3. Выберите вкладку Axe DevTools и выберите «Сканировать всю мою страницу», чтобы запустить сканирование Axe DevTools.

Линтинг

Вы можете использовать правила Angular ESLint для проверки вашего кода на наличие автоматизированных атрибутов a11y.

В eslint.json добавьте следующее, относящееся к специальным возможностям:

"@angular-eslint/template/accessibility-alt-text": 2,
"@angular-eslint/template/accessibility-elements-content": 2,
"@angular-eslint/template/accessibility-label-for": 2,
"@angular-eslint/template/no-positive-tabindex": 2,
"@angular-eslint/template/accessibility-table-scope": 2,
"@angular-eslint/template/accessibility-valid-aria": 2,
"@angular-eslint/template/click-events-have-key-events": 2,
"@angular-eslint/template/mouse-events-have-key-events": 2,
"@angular-eslint/template/no-autofocus": 2,
"@angular-eslint/template/no-distracting-elements": 2

Дополнительные сведения см. в последних правилах ESLint на GitHub .

Ваша отправная точка

Используя новые методы тестирования, вы можете выявить следующие проблемы в своем приложении с помощью аудитов Lighthouse и Axe, а также ручного VoiceOver:

Аудит Chrome DevTools Lighthouse с оценкой 82

Аудит доступности:

  • 🛑 Все страницы имеют одинаковый заголовок.
  • 🛑 Элементы должны иметь достаточный цветовой контраст.
  • 🛑 HTML должен иметь логический порядок, имя и роль.
  • 🛑 Вложенные флажки недоступны для программ чтения с экрана.
  • 🛑 Программа чтения с экрана не считывает значения ползунка
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

4. Определите уникальные заголовки страниц.

Предоставление уникальных, кратких заголовков страниц помогает пользователям, использующим службы a11y, быстро понять содержание и назначение веб-страницы. Заголовки страниц имеют решающее значение для пользователей с нарушениями зрения, поскольку они являются первым элементом страницы, объявляемым программным обеспечением для чтения с экрана.

Angular — это одностраничное приложение, поэтому большинство переходов, таких как переход на новую страницу, не требуют перезагрузки страницы. До недавнего времени это означало, что каждая страница имела одинаковый заголовок и не представляла никакой ценности для понимания содержания или цели страницы.

В Angular v14 Router добавил встроенный метод для определения уникальных заголовков страниц «из коробки». Это обеспечивает оптимизированный подход, позволяющий разработчикам следовать лучшим практикам создания заголовков страниц.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Все страницы имеют одинаковый заголовок.

Вы можете найти каждый из этих шагов под комментарием: TODO: #4. Define unique page titles.

Определите проблему

Чтобы выявить эту проблему, включите программу чтения с экрана и перемещайтесь между вкладками «Наш магазин» , «Наша история» и «Найти нас» , чтобы увидеть заголовки страниц:

  1. Включите VoiceOver.
  2. Используйте навигацию по вкладкам для перемещения между страницами.
  3. Убедитесь, что заголовок страницы в Angular всегда a11y.

Это проблема, поскольку заголовок вашей страницы должен быть уникальным , чтобы пользователь мог быстро понять, о чем страница, без необходимости перемещаться по ней.

Браузер Chrome с тремя открытыми вкладками и одинаковым заголовком страницы: «a11y в Angular».

Добавьте осмысленные заголовки страниц

Если страница или представление изменились, вам нужно правильно управлять заголовком страницы. Чтобы исправить это, вы используете встроенное свойство Angular Router.title для определения уникальных заголовков для каждой из ваших страниц.

  1. Добавьте уникальный заголовок к каждому из трех определенных маршрутов:

src/app/app-routing.module.ts

const routes: Routes = [
  { path: 'shop', component: ShopComponent, title: 'Our Shop – a11y in Angular' },
  { path: 'about', component: AboutComponent, title: 'Our Story - a11y in Angular' },
  { path: 'locate', component: LocationComponent, title: 'Find Us - a11y in Angular' },
  { path: '',   redirectTo: '/shop', pathMatch: 'full' },
  { path: '**', component: ShopComponent },
];

Это автоматически импортирует и использует Router's Title Service для управления изменением заголовка страницы при навигации, чтобы он соответствовал свойству заголовка, определенному в наших маршрутах. Вы также можете управлять более сложными заголовками страниц, используя собственную TitleStrategy .

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. Страницы теперь должны иметь уникальные заголовки!

Браузер Chrome с тремя открытыми вкладками и уникальным заголовком страницы: «Наш магазин — a11y в Angular», «Наша история — a11y в Angular», «Найти нас — a11y в Angular».

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • 🛑 Элементы должны иметь достаточный цветовой контраст.
  • 🛑 HTML должен иметь логический порядок, имя и роль.
  • 🛑 Вложенные флажки недоступны для программ чтения с экрана.
  • 🛑 Программа чтения с экрана не считывает значения ползунка
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

5. Обеспечьте достаточный цветовой контраст.

Ваш дизайн может показаться крутым, но это не так, если люди с нарушениями зрения, например дальтонизмом, не могут прочитать ваш контент. Рекомендации по обеспечению доступности веб-контента (WCAG 2.0) определяют ряд коэффициентов цветового контраста, которые обеспечивают доступность контента. В Angular и в Интернете вы можете определить цветовые палитры, которые гарантируют, что ваши компоненты будут соответствовать этим стандартам и будут видны пользователям с плохим зрением и дальтонизмом.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Элементы должны иметь достаточный цветовой контраст.

Вы можете найти каждый из этих шагов под комментариями: TODO: #5. Ensure adequate color contrast.

Используйте инструменты разработчика Chrome для выявления проблем с низкой контрастностью

Чтобы выявить эту проблему, используйте инструменты разработчика Chrome для проверки элементов вашего приложения.

  1. Используйте инструмент проверки, чтобы просмотреть кнопки со значками меню. Вы можете видеть, что контраст составляет 1,85, что намного ниже требований WCAG .

Chrome DevTools проверяет элемент кнопки «Домой» с низкой контрастностью

  1. Запустите проверку доступности в Lighthouse или сканирование Axe, чтобы увидеть проблемы с контрастностью.

Результаты аудита Chrome DevTools Lighthouse с ошибкой: «Цвета фона и переднего плана не имеют достаточного коэффициента контрастности»

Изменить цвет темы материала

Цветовая схема вашего компонента определяется в вашей пользовательской теме материала. Вы обновляете значение темы, чтобы оно соответствовало рекомендациям по соотношению цветового контраста.

Обновите тему «Материал», чтобы использовать более темный цвет текста, увеличивая контрастность ваших значков:

src/styles.scss

$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 900);

Вы также можете использовать встроенные инструменты специальных возможностей Chrome Developer Tools, чтобы найти цвет, соответствующий стандартам, или обновить отдельные значения цвета в Sass.

Проверьте изменения

Еще раз проверьте свои элементы и проверьте внесенные изменения. Теперь наша тема должна иметь достаточный коэффициент цветового контраста!

Chrome DevTools проверяет элемент кнопки «Домой» с достаточным контрастом

Аудит доступности

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • 🛑 HTML должен иметь логический порядок, имя и роль.
  • 🛑 Вложенные флажки недоступны для программ чтения с экрана.
  • 🛑 Программа чтения с экрана не считывает значения ползунка
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

6. Используйте семантический HTML

Нативные элементы HTML отражают ряд стандартных шаблонов взаимодействия, которые важны для доступности. Хотя абзац можно стилизовать как диапазон, а элемент div можно стилизовать как кнопку, семантический элемент HTML гарантирует, что программы чтения с экрана и навигация с помощью клавиатуры понимают взаимодействия и элементы управления вашего HTML.

При разработке компонентов Angular вам следует по возможности повторно использовать эти собственные элементы напрямую, а не переопределять хорошо поддерживаемое поведение. Это гарантирует, что страница имеет хорошую структуру контента и естественный поток контента, а также то, что вкладки расположены в логическом порядке, чтобы помочь пользователям перемещаться по веб-сайту с эффективным использованием клавиатуры.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 HTML должен иметь логический порядок, имя и роль.

Вы можете найти каждый из этих шагов под комментариями: TODO: #6. Use Semantic HTML.

Определите проблему

  1. Включите VoiceOver.
  2. Используйте навигацию по вкладкам, чтобы перейти на вкладку «Наша история» .
  3. Обратите внимание, что порядок табуляции не является последовательным.
  4. Нажмите «Покупки» e.
  5. Обратите внимание, что кнопка не распознается как кнопка.

Результаты аудита Chrome DevTools Lighthouse выдают ошибку: элементы заголовка расположены не в порядке последовательного убывания. Правильно упорядоченные заголовки, которые не пропускают уровни, передают семантическую структуру страницы, упрощая навигацию и понимание при использовании вспомогательных технологий. Узнать больше.

Изменение <div> на <button>

Замените пользовательский <div> кнопкой «Материал»:

src/app/shop/shop.comComponent.html

<button mat-flat-button 
  color="primary" 
  class="purchase-button"
  (click)="fauxPurchase()">
  Purchase
</button>

Используйте элементы заголовка последовательно

Измените порядок текста, чтобы использовать семантический HTML, и примените стиль, используя типографику Angular Material :

src/app/about/about.comComponent.html

<h2>Who are we?</h2>
<p class="mat-subheading-2">Have you ever thought, "wow, I love dumplings"?</p>
<p class="right mat-subheading-1">Who hasn't.</p>
<p class="center mat-subheading-1">We took it one step further and created Dumpling Dumpling,</p> 
<p class="center mat-subheading-1">double the dumpling, double the fun.</p>
<div class="spacer"></div>
<h2>How are we different?</h2>
<p class="mat-subheading-2">Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</p>
<p class="right mat-subheading-2">This shop is concept only.</p>

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. VoiceOver теперь распознает кнопку и текст читается в логическом порядке!

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • 🛑 Вложенные флажки недоступны для программ чтения с экрана.
  • 🛑 Программа чтения с экрана не считывает значения ползунка
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

7. Создайте выбираемые элементы управления с помощью Angular Material.

Одним из сложных шаблонов взаимодействия служб доступности являются вложенные элементы управления. Подумайте о подпунктах меню или вложенных флажках. Как указать пользователю, что вы можете выбрать подгруппу параметров или перейти к родительскому пункту меню?

В Angular упростите меню и элементы управления для создания компонентов с возможностью навигации, максимально упростив элементы управления. В этом примере вы используете список Angular Material, чтобы построить один пример этого шаблона взаимодействия.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Вложенные флажки недоступны для программ чтения с экрана.

Вы можете найти каждый из этих шагов под комментариями: TODO: #7. Create selectable controls with Angular Material.

Определите проблему

Чтобы выявить эту проблему, мы включим программу чтения с экрана и попытаемся установить вложенный флажок.

  1. Включите VoiceOver.
  2. Выбирайте разные вкусы начинки.
  3. Обратите внимание, что родительские флажки не указывают дочерних элементов при чтении VoiceOver. Как узнать, что флажок «Веганство» снят после того, как вы сняли флажок «Бок Чой» ?

Меню флажков «Начинки» с опциями: «Веганские начинки, бок-чой, тофу и мясо шитаке, курица, невозможное мясо».

A11y в угловом материале

Вы заменяете семантический флажок флажком Angular Material, который содержит встроенные знания об этом шаблоне взаимодействия. Важно отметить, что замена компонентов на Material не гарантирует доступности. Как и любой другой компонент, вам необходимо тестировать его вручную, поскольку существует множество способов реализовать Material в недоступном месте.

Замените флажки флажками материалов.

  1. Сначала добавьте новый список начинок и переменную для хранения выбранных вами вкусов начинки:

src/app/shop/shop.comComponent.ts

@Component(...)
export class ShopComponent implements OnInit {
  fillings: string[] = ['Bok Choy & Chili Crunch', 'Tofu & Mushroom', 'Chicken & Ginger', 'Impossible Meat & Spinach'];
  selectedFillings: string[] = [];

  fauxPurchase(): void {
    let flavor = '';
    this.selectedFillings.forEach(filling => {
      flavor = flavor + " " + filling
    })
  }
}
  1. Добавьте <mat-selection-list> , чтобы заменить эту беспорядочную группу флажков HTML:

src/app/shop/shop.comComponent.html

<mat-selection-list [(ngModel)]="selectedFillings" 
  aria-label="Dumpling fillings">
  <mat-list-option *ngFor="let flavor of fillings" 
    [value]="flavor" 
    color="primary">
    {{ flavor }}
  </mat-list-option>
</mat-selection-list>

Ваши комментарии TODO также показывают, где вы можете удалить неиспользуемый Sass в src/app/shop/shop.component.scss чтобы очистить ваш стиль.

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. Теперь ваши флажки можно выбирать, а навигация по ним стала более интуитивно понятной с помощью программы чтения с экрана!

Меню флажков «Начинки» с позициями: Начинки Бок Чой и чили, хрустящий тофу и грибы, курица и имбирь, невозможное количество мяса и шпината.

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • Все элементы управления доступны с помощью программ чтения с экрана.
  • 🛑 Программа чтения с экрана не считывает значения ползунка
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

8. Предоставьте контрольные метки с помощью ARIA.

Вы изменили семантические компоненты HTML и Material вашего приложения Angular, но для некоторых компонентов требуются определенные атрибуты, чтобы программы чтения с экрана могли полностью перемещаться по ним.

Спецификация доступных полнофункциональных интернет-приложений (WAI-ARIA или ARIA) Web Accessibility Initiative помогает устранить проблемы, с которыми невозможно справиться с помощью встроенного HTML. Он позволяет указать атрибуты, которые изменяют способ преобразования элемента в дерево доступности.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Программа чтения с экрана не считывает значения ползунка

Вы можете найти каждый из этих шагов под комментариями: TODO: #8. Provide control labels with ARIA.

Определите проблему

Чтобы выявить эту проблему, включите программу чтения с экрана и переместите ползунок:

  1. Включите VoiceOver.
  2. Перейдите к ползунку количества и измените значение.
  3. Обратите внимание, что метка значения отсутствует.

Результаты аудита Chrome DevTools Lighthouse выдают ошибку: поля ввода ARIA не имеют доступных имен. Когда поле ввода не имеет доступного имени, средства чтения с экрана объявляют его с общим именем, что делает его непригодным для использования пользователями, использующими средства чтения с экрана. Узнать больше.

Используйте атрибуты ARIA

Управление метками с использованием aria-label для <mat-slider> :

src/app/shop/shop.comComponent.html

<mat-slider
  aria-label="Dumpling order quantity slider"
  id="quantity"
  name="quantity"
  color="primary"
  class="quantity-slider"
  [max]="13"
  [min]="1"
  [step]="1"
  [tickInterval]="1"
  thumbLabel
  [(ngModel)]="quantity">
</mat-slider>

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. Теперь вы можете перемещать ползунок!

Аудит Chrome DevTools Lighthouse с прохождением аудита элементов управления ARIA для чтения с экрана.

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • Все элементы управления доступны с помощью программ чтения с экрана.
  • Слайдер использует атрибуты ARIA для предоставления метки.
  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.
  • 🛑 Изменения, ошибки и уведомления не анонсируются.
  • 🛑 Режим высокой контрастности не включен.

9. Добавьте мощь @angular/cdk/a11y

До сих пор вы полагались на встроенные инструменты Angular для решения распространенных проблем. Теперь давайте посмотрим на модуль a11y из CDK и на то, как он может помочь нам решить более сложные проблемы, специфичные для Angular.

К концу этого раздела вы продолжите этот курс, используя инструменты модуля Angular a11y.

Эти шаги вы можете найти под комментарием: TODO: #9. Add the power of @angular/cdk/a11y.

Импортируйте модуль

Добавьте модуль в свое приложение:

src/app/app.module.ts

import { A11yModule } from '@angular/cdk/a11y';

@NgModule({
  declarations: [...],
  imports: [
    A11yModule
  ],
  providers: [...],
  bootstrap: [...]
})

Что делает '@angular/cdk/a11y' ?

Модуль a11y предоставляет ряд инструментов для улучшения доступности и особенно полезен для авторов компонентов.

В следующих разделах вы добавите три общих сервиса: FocusTrap, LiveAnnouncer и HighContrast.

Дополнительные сведения обо всех других службах, предоставляемых @angular/cdk/a11y , см. в разделе «Доступность» .

10. Контролируйте фокус с помощью FocusTrap

Когда диалог или модальное окно открыто, пользователь взаимодействует только внутри него. Разрешение фокусу выйти за пределы диалогового окна смешивает контексты и создает состояние, в котором пользователь не знает, на какой странице он находится.

В Angular директива cdkTrapFocus захватывает фокус клавиши tab- внутри элемента. Это предназначено для создания доступного интерфейса для таких компонентов, как модальные диалоги, где фокус должен быть ограничен.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Фокус чтения с экрана в палитре цветов завершает диалоговое окно.

Эти шаги вы можете найти под комментариями: TODO: #10. Control focus with FocusTrap.

Определите проблему

Чтобы выявить эту проблему, включите программу чтения с экрана и откройте диалоговое окно выбора цвета.

  1. Включите VoiceOver.
  2. Используйте навигацию по вкладкам, чтобы изменить цвет.
  3. Проверьте, чтобы увидеть интуитивно понятный порядок фокусировки и захват фокуса в палитре цветов.

Веб-сайт магазина Dumpling Time в фиолетово-зеленой теме с открытым диалогом для выбора цвета упаковки пельменей

Добавить фокус-ловушку

cdkFocusTrap можно использовать для перехвата и управления порядком фокуса в пользовательских компонентах. Использование mat-dialog-content достаточно для решения большинства проблем путем захвата фокуса в диалоге. Добавьте атрибут cdkFocusInitial , чтобы определить начальную область фокуса для цвета оболочки клецок <mat-selection-list> в диалоговом окне выбора цвета.

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.comComponent.html

<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false" cdkFocusInitial>
  ...
</mat-selection-list>

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. Фокус теперь изначально установлен на «Изменить цвет» в диалоговом окне!

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • Все элементы управления доступны с помощью программ чтения с экрана.
  • Слайдер использует атрибуты ARIA для предоставления метки.
  • Палитра цветов имеет правильный захват фокуса.
  • 🛑 Изменения, ошибки и уведомления не анонсируются
  • 🛑 Режим высокой контрастности не включен.

11. Объявляйте об изменениях с помощью LiveAnnouncer.

Программы чтения с экрана должны получать уведомления, когда что-то на странице меняется. Представьте себе, что вы пытаетесь отправить форму или совершить покупку и не знаете, что возникла ошибка, препятствующая отправке формы. Это расстраивает!

LiveAnnouncer используется для объявления сообщений пользователям программ чтения с экрана с использованием региона aria-live, чтобы гарантировать, что программы чтения с экрана уведомляются об уведомлениях и изменениях страниц в реальном времени. Для получения дополнительной информации о регионах aria-live см. WAI-ARIA W3C . В Angular вызов LiveAnnouncer как службы является более тестируемым решением, чем атрибуты aria-live .

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Изменения, ошибки и уведомления не анонсируются.

Эти шаги вы можете найти под комментариями: TODO: #11. Announce changes with LiveAnnouncer.

Определите проблему

Чтобы выявить эту проблему, включите программу чтения с экрана и выберите «Купить» , не заполняя поля формы:

  1. Включите VoiceOver.
  2. Используйте навигацию по вкладкам, чтобы изменить цвет и совершить фиктивную покупку.
  3. Обратите внимание, что при выходе из диалога нет указания, какой цвет был выбран, и покупка не считывается.

Веб-сайт магазина Dumpling Time в розово-красной теме с открытым диалогом для выбора цвета упаковки пельменей

Добавьте LiveAnnouncer в свой код

Добавьте LiveAnnouncer и объявляйте выбор цвета и фиктивную покупку в виде строки. В реальной реализации это можно прочитать при переходе к сторонней платежной системе или при ошибках формы.

  1. Добавьте объявление при выборе цвета:

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.comComponent.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ColorPickerDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ColorPickerDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ColorDialogData,
    private liveAnnouncer: LiveAnnouncer) { }

  public changeColor(color: string): void {
    this.liveAnnouncer.announce(`Select color: ${color}`);
    this.dialogRef.close();
  }
}
  1. Добавьте объявление при совершении фиктивной покупки:

src/app/shop/shop.comComponent.ts

import { LiveAnnouncer } from '@angular/cdk/a11y';

@Component(...)
export class ShopComponent implements OnInit {

  constructor(private liveAnnouncer: LiveAnnouncer) { }

  fauxPurchase(): void {
    let flavor = '...';
    const fakePurchase = `Purchase ${this.quantity} ${flavor}dumplings in the color ${this.color}!`;

    this.liveAnnouncer.announce(fakePurchase);
  }
}

Проверьте изменения

Снова включите программу чтения с экрана и проверьте изменения. Теперь вы будете уведомлены о своих ошибках!

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • Все элементы управления доступны с помощью программ чтения с экрана.
  • Слайдер использует атрибуты ARIA для предоставления метки.
  • Палитра цветов имеет правильный захват фокуса.
  • Объявляются изменения, ошибки и уведомления
  • 🛑 Режим высокой контрастности не включен.

12. Включите режим высокой контрастности.

Microsoft Windows поддерживает функцию специальных возможностей, называемую режимом высокой контрастности. В этом режиме изменяется внешний вид всех приложений, включая веб-приложения, чтобы значительно повысить контрастность. В Angular вы хотите уважать предпочтения пользователя в своем приложении.

HighContrastModeDetector позволяет определить, находится ли браузер в данный момент в среде с высоким контрастом.

Internet Explorer, Microsoft Edge и Firefox поддерживают этот режим. Google Chrome не поддерживает режим высокой контрастности Windows. Эта служба не обнаруживает режим высокой контрастности, добавленный расширением браузера Chrome High Contrast.

К концу этого раздела ваше приложение пройдет следующий аудит:

  • 🛑 Режим высокой контрастности не включен.

Эти шаги вы можете найти под комментариями: TODO: #12. Enable HighContrast mode.

Определите проблему

Чтобы выявить эту проблему, откройте свое приложение в Internet Explorer, Microsoft Edge или Firefox, включите режим высокой контрастности и обратите внимание на отсутствие изменений:

  1. Откройте свое приложение в Internet Explorer, Microsoft Edge или Firefox.
  2. Включите режим высокой контрастности.
  3. Обратите внимание, что приложение не изменилось.

Добавить поддержку режима высокой контрастности

В styles.scss используйте миксин cdk-high-contrast , представленный в @angular/cdk/a11y чтобы добавить контур к кнопкам в режиме высокой контрастности:

src/приложение/магазин/shop.comComponent.scss

@use '@angular/cdk';

.purchase-button {
    border-radius: 5px;
    background-color: mat.get-color-from-palette(mat.$pink-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$pink-palette, 50);
    }
}

:host-context(.dark-theme) {
  .purchase-button {
    background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);

    @include cdk-high-contrast {
      outline: solid 1px;
      background-color: mat.get-color-from-palette(mat.$light-green-palette, 50);
    }
  }
}

Проверьте изменения

Обновите приложение и проверьте изменения. Вы добавили контур к кнопке в режиме высокой контрастности!

Веб-сайт магазина Dumpling Time в красно-розовой теме с включенным режимом высокой контрастности, а кнопка покупки теперь четко выделена толстым красным контуром.Веб-сайт магазина Dumpling Time выполнен в сине-зеленой теме с включенным режимом высокой контрастности, а кнопка покупки теперь четко выделена толстым синим контуром.

Аудит доступности:

  • Все страницы имеют уникальные заголовки.
  • ✅Цвета имеют достаточную контрастность
  • Семантический HTML обеспечивает логическое взаимодействие.
  • Все элементы управления доступны с помощью программ чтения с экрана.
  • Слайдер использует атрибуты ARIA для предоставления метки.
  • Палитра цветов имеет правильный захват фокуса.
  • Объявляются изменения, ошибки и уведомления
  • Включен режим высокой контрастности

13. Поздравляем!

Поздравляем, вы решили распространенные проблемы с веб-доступностью в своем приложении Angular! 🎉

Чтобы увидеть все решения, посетите main ветку.

На веб-сайте магазина Dumpling Time в красно-розовой теме показаны все изменения, внесенные в эту кодовую лабораторию.На веб-сайте магазина Dumpling Time в сине-зеленой теме показаны все изменения, внесенные в эту кодовую лабораторию.Аудит Chrome DevTools Lighthouse с оценкой 100/100

Теперь вы знаете ключевые шаги, необходимые для устранения восьми распространенных ошибок в вашем приложении Angular.

Узнать больше

Ознакомьтесь с этими лабораториями кода:

Прочтите эти материалы: