Эта статья — вольный перевод оригинала. Я добавляю свои примеры и мысли, пишу как чувствую и ставлю смайлики :) Автор статьи сказал, что ему понравилась моя интерпретация! Джерард занимается доступностью в Twitter и попросил поделиться с вами ссылкой на его курсы по доступности. Курсы лаконичные и очень понятные, я их посмотрела по 10-дневной бесплатной подписке. Итак, к делу!
Глафира Жур.
Опасности, которые таит в себе ARIA Скопировать ссылку
В оригинальной статье введение более содержательное, так что почитайте его хотя бы ради практики английского языка :) Я передам только несколько тезисов — прим. переводчицы.
ARIA — (Accessible Rich Internet Applications) это набор атрибутов, который позволяет сделать наши приложения более доступными, особенно если они написаны на JS. Из моего опыта — это, например, легаси-код, где давно-давно наверстали дивами, а теперь надо как-то добавить доступность, но нет доступа к HTML.
Когда вы узнаёте о существовании ARIA, вы начинаете везде использовать эти атрибуты, где бы только ни захотели. Например, у вас React-компонент (типичный, на дивах), и вам нужно, чтобы скринридер начал читать его правильно, поэтому вы добавляете компоненту роль, например, role="button"
и какие-то ещё важные ARIA-атрибуты (aria-required
, aria-disabled
и так далее), но забываете про клавиатуру. Ошибка тут в том, что вы мало что знаете про ARIA, поэтому вероятность упустить нечто важное крайне высока. Дальше выясняется, что некоторые ARIA-атрибуты могут не иметь поддержки на определённых платформах или сочетаниях браузер + скринридер.
Если вы хотите познакомиться с ARIA — начинайте с официальных спецификаций. Не нужно сразу читать их глубоко и полностью, но парочку секций лучше изучить. Например, самое важное, с чем следует ознакомиться в спеке — это понятие роли.
Роль — это семантика вашего элемента, подсказка для ассистивных технологий, что можно делать с этим элементом, как его обрабатывать, как с ним взаимодействует клавиатура и так далее.
В ассистивные технологии входят скринридеры, брайлевские клавиатуры, голосовые помощники и другие средства доступа к информации, помимо привычных клавиатур, экранов и мышей.
Важно: роли (и вообще любые ARIA-атрибуты) не добавляют элементам никаких стилей и поведения!
У ролей есть классификация. Например, бывают роли для виджетов, для структуры документа, для лайв-областей, которые как-то обновляются на фоне независимо от действий пользователя и о чём-то ему сообщают. Практически для каждой роли есть свой набор обязательных ARIA-атрибутов. Некоторые роли нельзя использовать отдельно от родительских ролей.
Вот и пробежались по введению в статью :) Переходим к правилам!
Пять правил использования ARIA Скопировать ссылку
Если вы уже понимаете, что вынуждены как-то накручивать доступность на ваши интерфейсы, нужно следовать нескольким основным правилам. Это облегчит принятие решений при разработке приложений и конкретно виджетов.
Правило 1 Скопировать ссылку
Не используйте ARIA
Читая это правило, я всегда очень радуюсь — так однозначно и бескомпромиссно оно звучит :) На практике смысл его в том, что сначала вы должны полностью положиться на HTML и использовать его семантику, и только тогда, когда вам не хватило или есть какой-то сложный составной случай (например, аккордеон или вкладки) — тогда подключайте ARIA. Также приходится использовать эти волшебные атрибуты в уже упомянутом мной легаси-коде, где нет доступа к HTML и можно только с помощью JS добавлять что-то к существующим тегам.
Правило 2 Скопировать ссылку
Не изменяйте семантику нативных контролов.
Вы уже начали писать чистый, красивый и семантичный HTML, но поняли, что везде используете таблицы для вывода простых списков. У вас есть возможность явно задать элементу роль, чтобы переопределить его семантику:
- была
table
, и скринридер говорил, что вы попали в таблицу, такой-то столбец, такая-то строка; - вы не решились перевёрстывать все места и просто добавили таблице
role="list"
, её детям тоже расставили нужные роли; - скринридер теперь читает это как список.
Так вот, не переопределяйте дефолтную семантику без острой необходимости! Лучше замените тег: <table>
превратится в <ul>
или <ol>
)!
Когда мне приходится менять семантику:
- если нужно спрятать таблицы для раскладки от скринридера (чтобы он не читал, что это ячейка таблицы) — задаю
role="presentation"
для таблицы; - если
<svg>
со значимой картинкой — могу задатьrole="img"
; - если это
<div>
в составе виджета и для него нет HTML-эквивалента (например,tab
,tablist
,tabpanel
); - иногда бывают баги, например, есть
<ul>
, и мы стилями сбрасываем оформление спискаlist-style: none
, что в Safari может вызвать удаление роли списка для скринридера. Один из лайфхаков в таком случае — снова явно определить семантику, задавrole="list"
для<ul>
; - и другие.
Важно: если вы сейчас явно задаете вашему тегу role
(особенно если это не <div>
) — вы скорее всего неправильно используете ARIA.
Правило 3 Скопировать ссылку
Все интерактивные роли должны быть доступны с клавиатуры.
Нативные контролы уже доступны с клавиатуры, нам не надо ничего делать. Но если у вас <div role="button">
, то вы обязаны узнать, что ожидается от роли с точки зрения взаимодействия с клавиатурой и добавить это. В нашем случае с кнопкой — это активация по Enter и Space.
Для виджетов тоже существует свое определенное, уже привычное пользователю взаимодействие с клавиатурой: например, фокус зациклен в модальном окне и не выходит за его пределы, пока окно открыто.
Напоминаю, роль или любой другой ARIA-атрибут не добавляют никакого поведения и стилей элементам, они просто сообщают ассистивным технологиям необходимую информацию о назначении, взаимодействии, состоянии.
Правило 4 Скопировать ссылку
Не используйте role="presentation"
и aria-hidden="true"
на видимых фокусабельных элементах.
role="presentation"
— это особенная роль. Суть в том, что она полностью убирает любую семантику с элемента и с его прямых обязательных потомков. Например, если поставить role="presentation"
на <ul>
— роль также слетит с <li>
. Если задать ее интерактивному контролу — ассистивные технологии перестанут его воспринимать. Если на контрол было навешено какое-то поведение — оно сохранится, но пользователь скринридера никогда не узнает, что вообще можно сделать с этим элементом, ведь скринридер разве что зачитает текст внутри, если он там есть.
aria-hidden
— способ спрятать что-то от ассистивных технологий. Этот атрибут не меняет вида элемента и не убирает с него никакого поведения. Элемент по-прежнему рендерится на странице, но скринридер его больше не видит.
aria-hidden
не стоит просто так брать и использовать, чтобы скрыть контент от скринридера. Разработчики часто вставляют его везде (на видимых элементах, на невидимых), и получается, что у разных пользователей — разная информация: зрячий видит и читает текст, который скрыт «за ненадобностью» и недоступен незрячему. Это противоречит равному доступу к контенту и функциональности.
Важно: не следует использовать aria-hidden
на фокусабельных элементах, а также на контейнере, который содержит фокусабельные элементы, поскольку они остаются доступными с клавиатуры. Такие элементы нужно убирать из порядка фокуса. Один из способов — добавлять интерактивным контролам tabindex="-1"
. Подробнее о проблеме можно почитать в статье «[aria-hidden="true"]
elements contain focusable descendants», а также посмотреть примеры ошибок в описании правила aria-hidden-focus
инструмента axe-core. Про другие особенности aria-hidden
— читайте на MDN.
Правило 5 Скопировать ссылку
Все интерактивные элементы обязаны иметь доступное имя.
Любой пользователь должен понимать, что за контрол он собирается активировать. Для этого контрол уже содержит роль, то есть определен его тип: кнопка, поле ввода, интерактивное меню. Но типа недостаточно, нужно еще и понятное, лаконичное, уникальное имя.
Имя можно задавать разными способами в зависимости от ситуации (я знаю как минимум четыре), но важно, чтобы оно было в итоге получено ассистивными технологиями и передано пользователю.
Нельзя забывать, что люди могут использовать ваши интерфейсы тысячей разных способов. Например, в случае с лейблами, пользователь, который взаимодействует с интерфейсами речью (говорит устройству, что нужно сделать), полагается на видимое имя элемента — например, текст кнопки. Называет его, и кнопка нажимается.
Как в таком случае программно нажать кнопку-иконку, у которой нет имени? Нажмется ли кнопка, если её лейбл — это просто наложенный для красивого эффекта <div>
с текстом?
Заключение Скопировать ссылку
Вот и они, самые базовые, самые основные правила использования ARIA в интерфейсах. Даже такое базовое их понимание очень сильно улучшит ваше отношение к той работе, которую вы делаете.
Ну и конечно же помните, что нельзя просто так взять и накрутить доступность! Думайте о пользователях и его удобстве, помогайте им понять, что и как у вас работает, как им достичь цели захода на сайт: купить товар, заказать услугу, получить информацию, отправить данные.
И огромное спасибо, что интересуетесь доступностью! Вместе победим!