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

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

Проблемы со зрением могут варьироваться от неспособности различать цвета до полного отсутствия зрения.

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

  • Сделайте содержимое понятным за счет использования текстовых альтернатив для всех нетекстовых видов контента.
  • Обеспечьте тестирование всех компонентов на функциональность без звука.

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

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

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

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

Доступен ли ваш компонент?

При аудите доступности вашего приложения спросите себя:

  • Можно ли пользоваться компонентом при помощи исключительно клавиатуры? Управляет ли он фокусом и избегает ли ловушек фокуса? Реагирует ли на соответствующие события клавиатуры?
  • Можно ли использовать компонент со скринридером? Есть ли альтернативный текст для визуальной информации? Добавлена ли семантическая информация с помощью ARIA?
  • Может ли компонент работать без звука? Выключайте колонки при проверке этого.
  • Может ли компонент работать без цвета? Обеспечьте возможность использования компонента теми, кто не различает цвета. Полезным инструментом для симуляции цветовой слепоты является расширение Chrome SEE (в нем вы можете проверить все четыре доступных формы цветовой слепоты). Сходным функционалом обладает также расширение Daltonize.
  • Может ли компонент работать в режиме повышенной контрастности? Все современные операционные системы поддерживают режим высокой контрастности. В Chrome есть расширение Contrast, которое поможет вам в тестировании этого.

Нативные элементы управления (такие как <button> и <select>) обладают доступностью, встроенной в браузеры. Они фокусируются при помощи клавиши TAB, откликаются на события с клавиатуры (клавиши ввода, пробела, а также стрелочные клавиши) и обладают семантическими ролями, состояними и свойствами, используемыми инструментами доступности. Стили по умолчанию также должны соответствовать требованиям доступности, перечисленным выше.

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

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

Может ли компонент использоваться при помощи исключительно клавиатуры?

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

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

Управление фокусом сложного элемента Управление фокусом внутри сложного элемента

Использование tabindex

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

Есть три типа значений tabindex:

  • tabindex="0" это самый распространенный вариант, он помещает элемент соответственно естественному порядку (определяемому DOM).
  • значение tabindex больше нуля размещает элемент согласно вашему порядку — все элементы с позитивным tabindex будут посещены, раньше элементов, размещенных в естественном порядке.
  • tabindex равный -1 делает элемент программно фокусируемым, но вне порядка переключения клавишей TAB.

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

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

О техниках управления фокусом есть подробная статья на MDN.

Использование autofocus

HTML-атрибут autofocus позволяет задать элемент, который автоматически получит фокус при загрузке страницы. Этот атрибут поддерживается всеми управляющими элементами форм, включая <input>. Для автофокуса элементов в ваших компонентах вызывайте метод focus(), поддерживаемый всеми фокусируемыми элементами HTML (примерно так: document.getElementById(‘myButton’).focus()).

Добавление взаимодействия с клавиатуры

Раз ваш компонент фокусируем, попытайтесь создать хорошее взаимодействие с клавиатуры при фокусировании на элементе, добавив соответствующие события клавиатуры — например, позволив пользователю использовать стрелочные клавиши для выбора опций меню, а пробел или ввод для активации кнопок. Больше информации можно найти в ARIA design patterns guide.

Наконец, обеспечьте доступность информации о применяемых сочетаниях клавиш (“горячих кнопках”). Например, распространенной практикой является наличие текста, информирующего о наличии клавиатурных сочетаний. Например, “Нажмите ‘?’, чтобы узнать о горячих кнопках”. Также для этого могут использоваться другие подсказки.

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

Можно ли использовать ваш компонент с помощью скринридера?

Около 1–2% пользователей используют скринридер. В конце этой статьи я перечислю несколько бесплатных скринридеров — попробуйте проверить свой компонент хотя бы на одном из них. Можете ли вы определить всю важную информацию и взаимодействовать с компонентом исключительно при помощи клавиатуры и скринридера?

Следующие вопросы должны помочь вам решить проблемы пользователей скринридеров:

У всех ли компонентов и изображений есть осмысленный альтернативный текст?

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

Например, если ваш компонент <fancy-menu> выводит только иконку следующего типа…

Иконка меню настроек

Иконка меню настроек

…для индикации того, что это меню настроек, ей нужен альтернативный текст (например “настройки”), передающий эту информацию. В зависимости от контекста, это может быть атрибут alt, атрибут aria-label или aria-labelledby, или простой текст в теневом DOM. Основные технические советы вы найдете в кратком справочнике WebAIM.

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

Предоставляют ли ваши компоненты семантическую информацию?

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

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

Например, кастомный компонент <fancy-slider> может взять ARIA роль slider, в которой есть соответствующие атрибуты ARIA: aria-valuenow, aria-valuemin и aria-valuemax. Привязывая эти атрибуты к соответствующим свойствам кастомного компонента, вы можете позволить пользователям вспомогательных технологий взаимодействовать с элементом, изменять его значение и даже вызывать изменение визуальной презентации элемента.

fancy-slider с ARIA ролью и атрибутами

<fancy-slider role="slider" aria-valuemin="1" aria-valuemax="5" aria-valuenow="2.5"></fancy-slider>

Могут ли пользователи понять все независимо от цвета?

Цвет не должен быть единственным средством передачи информации для таких случаев как индикация статуса, подсказки или отличительного свойства визуального компонента. Например, если вы создали компонент <fancy-map>, используя цвет для различения уровня пробок на дорогах, вам надо предложить альтернативные методы для определения уровня трафика — одним из вариантов может быть выведение всплывающей подсказки с такой информации при наведении на элемент.

Имеется ли достаточный контраст между текстом/изображениями и фоном?

Любой текстовый контент, выведенный в вашем компоненте должен соответствовать минимальным требованиям контрастности (AA). Подумайте также о создании высоконтрастной темы уровня контрастности ААА и обеспечьте, чтобы встроенные стили в браузере работали, если пользователю потребуется максимальный контраст или другие цвета. В качестве помощи при дизайне вы можете использовать Color Contrast Checker.

Безопасен ли движущийся и мерцающий контент в ваших компонентах?

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

Инструменты для тестирования доступности

Для отладки доступности визуальных компонентов есть ряд инструментов:

  • aXe — библиотека для автоматизированного тестирование доступности, работающая внутри фреймворка для тестирования или браузера.
  • расширение Accessibility DevTools для Chrome предоставляет аудит для обнаружения проблем с доступностью, включая проблемы, связанные с теневым DOM. Оно работает на основе модуля Accessibility DevTools, в нем доступен интерфейс командной строки, что позволяет использовать его в системах непрерывной интеграции.

Accessibility DevTools в Chrome

В дополнение к аудиту, расширение Accessibility DevTools показывает и советы по сочетаниям цветов — на примере предложены сочетания контрастности AA и AAA. Выбор какого-либо из вариантов будет применен к выделенному узлу DOM.

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

нативное инспектирование доступности в Chrome

Скоро в инструментах разработчика будет нативное инспектирование доступности. Вы можете попробовать уже сейчас.

  • Tenon.io — полезен для тестирования распространенных проблем с доступностью. Tenon хорошо интегрируется с системами сборки, браузерами (через расширения) и даже текстовыми редакторами.
  • Вы можете проверить, как вспомогательные технологии видят контент, используя Accessibility Inspector (Mac), или Windows Automation API Testing Tools и AccProbe (Windows). Также вы можете увидеть создаваемое Chrome дерево доступности, перейдя на страницу chrome://accessibility.
  • Лучший способ протестировать поддержку скринридеров на Mac это использование утилиты VoiceOver. Для ее включения/отключения используйте ⌘F5, Ctrl+Option ←→ для перемещения по странице и Ctrl+Shift+Option + ↑↓ для перемещения вверх/вниз по дереву. Для более полных инструкций смотрите полный список команд VoiceOver и список команд VoiceOver для Web.
  • tota11y это полезный визуализатор проблем со вспомогательными технологиями, разработанный Khan Academy. Это скрипт, добавляющий кнопку к вашему документу, при нажатии на которую запускаются плагины, обнаруживающие такие вещи как недостаточный контраст и прочие нарушения a11y.
  • ally.js (автор Rodney Rehm) это библиотека, пытающаяся упростить добавление отдельных возможностей доступности в ваше приложение. Она помогает делать запросы к DOM для всех фокусируемых или проходимых табом элементов, захватывает фокус отдельных поддеревьев DOM, помогает определять, как изменился фокус, а также содержит еще несколько вспомогательных функций.
  • в Windows есть быстро набирающий популярность бесплатный открытый скринридер NVDA,обладающий полным набором функций. Однако учтите, что зрячим пользователям освоить его намного сложнее, чем VoiceOver.
  • ChromeLens облегчает создание дизайна для слабовидящих. Он также обладает отличной поддержкой для визуализации путей навигации с клавиатуры.

ChromeLens

Расширение ChromeLens эмулирует различные формы слепоты, отслеживает переходы по табам и дает аудит доступности

  • ChromeVox это скринридер, встроенный на устройствах ChromeOS и доступный как расширение Chrome. Однако на данный момент он не может читать содержимое теневого DOM.

P.S. Если вы хотите узнать больше об основах доступности, есть бесплатный курс на Udacity.