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

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

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

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

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

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

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

Что вы построите

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

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

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

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

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

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

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. Нажмите «Создать отчет» , чтобы запустить аудит доступности в Lighthouse.

Пример вкладки Lighthouse с кнопкой для создания отчета во вкладке инструментов разработчика Chrome.

Топор

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

Ворсинки

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

В 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. Определите уникальные заголовки страниц.

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

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

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

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

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

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

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

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

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

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

В браузере Chrome открыто три вкладки с одинаковым заголовком страницы: 'a11y in 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 для управления изменением заголовка страницы при навигации в соответствии со свойством title, определенным в наших маршрутах. Вы также можете управлять более сложными заголовками страниц, используя пользовательскую TitleStrategy .

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

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

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

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

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

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

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

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

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

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

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

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

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

Инструменты разработчика Chrome: проверка элемента кнопки «Домой» при низкой контрастности

  1. Чтобы выявить эти проблемы с контрастностью, выполните проверку доступности в Lighthouse или сканирование с помощью axe.

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

Изменить цвет темы Material Design

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

Обновите тему оформления Material, используя более темный цвет текста и повысив контрастность значков:

src/styles.scss

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

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

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

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

Инструменты разработчика Chrome: проверка элемента кнопки «Домой» с достаточным контрастом

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

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

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

Встроенные HTML-элементы отражают ряд стандартных шаблонов взаимодействия, важных для доступности. В то время как абзац можно оформить как элемент `<span>`, а элемент `<div>` — как кнопку, семантические HTML-элементы гарантируют, что программы чтения с экрана и навигация с клавиатуры будут понимать взаимодействия и элементы управления вашего HTML-кода.

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

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

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

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

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

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

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

Замена элемента <div> на кнопку <button>

Замените пользовательский тег <div> на кнопку Material Design:

src/app/shop/shop.component.html

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

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

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

src/app/about/about.component.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 упрощение меню и элементов управления для создания навигационных компонентов достигается за счет максимально возможного упрощения элементов управления. В этом примере вы используете ListBox из 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.component.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.component.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-приложении, но для полноценной навигации по некоторым компонентам программам чтения с экрана требуются определенные атрибуты.

Спецификация Accessible Rich Internet Applications (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.component.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>

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

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

Проверка работоспособности элементов управления ARIA для программ чтения с экрана в Chrome DevTools Lighthouse прошла успешно.

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

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

9. Добавьте возможности @angular/cdk/a11y

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

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

Эти шаги вы найдете в комментарии: 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 в фиолетово-зеленой тематике с открытым диалогом для выбора цвета упаковки пельменей.

Добавить FocusTrap

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

src/app/shop/color-picker/color-picker-dialog/color-picker-dialog.component.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.component.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.component.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/app/shop/shop.component.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.

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

Посмотрите эти практические занятия:

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