Введение в ARIA

Кратко
ARIA (Accessible Rich Internet Applications) — это набор дополнительных атрибутов, которые расширяют возможности HTML, SVG и других языков для создания более доступных интерфейсов.
ARIA помогает повысить уровень доступности элементов или сделать статичную страницу динамическим веб-приложением для пользователей вспомогательных технологий. С помощью ARIA-разметки можно улучшить доступность интерактивных элементов, связать элементы друг с другом, указать в каком состоянии они находятся, отметить изменения на странице или описать структуру документа.
ARIA не влияет на внешний вид элементов и их поведение, а также не изменяет DOM. ARIA-атрибуты изменяют только то, как с элементами и страницами взаимодействуют браузеры, Accessibility API и вспомогательные технологии.
Кому помогает
Главные пользователи ARIA — это люди с визуальными, моторными и когнитивными особенностями, которые пользуются вспомогательными технологиями и настройками доступности в операционных системах или браузерах. Это могут быть:
- Скринридеры.
- Дисплеи Брайля.
- Экранные лупы.
- Альтернативные устройства ввода и манипуляторы — выносные компьютерные кнопки, головные указатели, виртуальные клавиатуры.
- Голосовое управление и программы для преобразования текста в речь.
Пользователи вспомогательных технологий обычно пользуются для навигации клавиатурой.
Как это понять
Внешний вид элементов не всегда совпадает с их функциями. К примеру, элемент в демо выглядит внешне как кнопка с текстом «Очистить форму».
Для этого элемента используется семантически нейтральный тег <div>. Поэтому для пользователей скринридеров это не кнопка, и они не могут сфокусироваться на элементе.
<div class="button button-blue">Очистить форму</div> Скопировать
В этой ситуации ARIA поможет превратить <div> в кнопку. Добавим ARIA-роль button, а ещё поместим элемент в порядок фокуса с помощью HTML-атрибута tabindex="0".
<div class="button button-blue" role="button" tabindex="0">Очистить форму</div> Скопировать
Теперь элемент доступен для скринридеров. Пользователи могут установить на нём фокус и узнать, что это кнопка с названием «Очистить форму».
Самое лучшее решение проблемы с доступностью этой кнопки — HTML-тег <button>. Тогда не нужно добавлять к элементу дополнительные атрибуты и отслеживать клики с помощью скрипта. Это всё уже есть в теге по умолчанию. Звучит странно, но одно из главных правил использования ARIA — стараться не использовать ARIA.
<button class="button button-blue">Очистить форму</button> Скопировать
Более сложный пример — сообщение об успешности или неуспешности действия. Как рассказать пользователям вспомогательных технологий, что на странице что-то произошло? Например, что форма успешно очищена.
Тут снова ARIA спешит на помощь. Добавим для сообщения об успешной очистке формы role="status" и свяжем с ним кнопку с помощью атрибута aria-controls. Благодаря этой ARIA-роли скринридер автоматически объявит сообщение, когда пользователь нажмёт на кнопку.
<button class="button button-aqua" aria-controls="message">Очистить форму</button> <div class="status-message" role="status" id="message"></div> Скопировать
Когда не нужно использовать
Мастерство владения ARIA заключается не столько в том, как это использовать, а когда это не стоит использовать.
ARIA Spec for the Uninitiated: Part 3, Джерард Коэн.
ARIA вообще не нужна тогда, когда нам хватает возможностей HTML, SVG и других языков. Поэтому вместо <div role="button"> лучше использовать <button>, а вместо <div role="main"> — <main>. У семантических HTML-элементов уже есть практически всё, что нужно для доступности. К примеру, в них встроены нужные роли и функциональность в случае интерактивных элементов.
Есть несколько ресурсов, которые помогут быстро узнать о встроенных ролях HTML-тегов:
- HTML-элементы и доступные имена.
- Периодическая таблица семантики.
- Таблица с HTML-элементами, встроенными ролями и возможными атрибутами из спецификации ARIA in HTML.
Когда пригодится
ARIA пригодится во всех случаях, когда возможностей HTML недостаточно. То есть, когда нет элементов с нужными ролями, свойствами и состояниями. Дополнительные атрибуты понадобятся в нескольких ситуациях:
- Динамическое обновление контента. Например, таймеры, оповещения, подгружающиеся не сразу части страниц.
- Кастомные интерактивные элементы и улучшение навигации с клавиатуры, особенно когда используется JavaScript. Примеры — выпадающий список, вкладки, тултип или всплывающее окно.
- Добавление дополнительных ориентиров на страницу. Это такие части страницы, по которым могут быстро перемещаться пользователи вспомогательных технологий. Примеры — область вкладок или поиска.
- Исправление проблем с доступностью в браузерах и для вспомогательных технологий из-за разной поддержки фич из HTML, CSS и других языков.
Как устроено
ARIA состоит из трёх частей — ролей, состояний и свойств.

Роли — основные цели и функции элемента. Задаются через role="".
Роли бывают разных типов. Одни могут отвечать за интерактивные элементы, к примеру, button и tab. Какие-то роли нужны для создания ориентиров на странице. Например, search и banner.
Есть роли для составных элементов, для которых нужны конкретные дочерние элементы. Например, у элемента с ролью list должен быть минимум один вложенный элемент с ролью lisitem. Это логично, ведь список делают списком пункты в нём.
Состояния (states) — в каком состоянии находятся интерактивный или неинтерактивный элемент.
Свойства (properties) — дополнительные функции элемента.
Состояния и свойства похожи друг на друга и задаются через атрибут aria-*="". Их часто объединяют и называют ARIA-атрибутами. Основная разница между ними в том, что значения атрибутов свойств часто не так сильно изменяются, как у атрибутов состояний. К примеру, значение свойства aria-label изменяется реже, чем состояния aria-checked.
ARIA-атрибуты тоже бывают разными. Какие-то атрибуты можно сочетать практически со всеми ролями элементов, например, aria-live и aria-label. Какие-то подходят только для интерактивных элементов, например, aria-hidden и aria-pressed. Есть атрибуты, которые обязательно нужны для определённых ролей. К примеру, у элемента с ролью combobox обязательно должно быть состояние aria-expanded.
Полные список ролей и список атрибутов из спецификации ARIA 1.2.
Правила использования
Есть пять основных правил использования ARIA.
Не используйте ARIA
Не используйте ARIA, если можно использовать HTML-теги и атрибуты.
В большинстве случаев вместо ARIA-атрибутов можно использовать семантические HTML-теги.
<!-- Неправильно ⛔ --> <div role="banner"> <div role="navigation"></div> </div> <!-- Правильно ✅ --> <header> <nav></nav> </header> Скопировать
Не изменяйте семантику
Не изменяйте встроенную семантику элементов без серьёзной необходимости.
Когда используете ARIA-роли, встроенные роли HTML-тегов перезаписываются. Поэтому для кастомных элементов лучше использовать семантически нейтральные <div> и <span>, если это не исключительный случай.
<!-- Неправильно ⛔ --> <h2 role="tab">Я первая вкладка</h2> <!-- Правильно ✅ --> <div role="tab"> <h2>Я первая вкладка</h2> </div> Скопировать
Все интерактивные элементы доступны для клавиатуры
Роль — это обещание, что элемент будет вести себя в соответствии с ней. Если это интерактивный элемент, то он должен получать фокус с клавиатуры. К примеру, между вкладками принято перемещаться стрелками вправо и влево, а раскрывать нажатием на Enter или пробел.
Для того, чтобы сделать кастомный элемент интерактивным, используют HTML-атрибут tabindex. Старайтесь избегать положительных чисел в качестве значения атрибута и используйте его только там, где это действительно нужно. К примеру, зрячим пользователям клавиатуры не нужен фокус на параграфах, заголовках и похожем текстовом содержимом страницы.
<!-- Неправильно ⛔ --> <span role="button" tabindex="1">Загрузить фото</span> <!-- Правильно ✅ --> <span role="button" tabindex="0">Загрузить фото</span> Скопировать
Подробнее про навигацию с клавиатуры для разных интерактивных элементов рассказано в разделе про паттерны APG (ARIA Authoring Practices Guide, Руководства по авторским ARIA-практикам).
Будьте осторожны с role="presentation" и aria-hidden="true"
Не используйте role="presentation" и aria-hidden="true" на видимых элементах, которые находятся в порядке фокуса.
Роль presentation удаляет семантику элемента. Интерактивный элемент останется в порядке фокуса даже со сброшенной семантикой. В этом случае пользователи скринридеров смогут на нём сфокусироваться, но не узнают роль элемента.
Свойство aria-hidden скрывает элемент от скринридеров и других вспомогательных технологий, но не скрывает его визуально. Если используете этот ARIA-атрибут на неинтерактивном элементе с вложенным интерактивным, то вложенный элемент унаследует этот атрибут. Это тоже приведёт к проблемам с доступностью для вспомогательных устройств.
<!-- Неправильно ⛔ --> <button role="presentation">Передать привет</button> <button aria-hidden="true">Передать привет</button> <div aria-hidden="true"> <button>Передать привет</button> </div> <!-- Правильно ✅ --> <!-- Описание картинки берётся из параграфа, а с параграфом связан <div> с ролью картинки --> <div role="img" aria-labelledby="caption"> <img src="dog.png" alt="" role="presentation"> <p id="caption">Собака наклонила голову, прижала уши и смотрит с интересом прямо в камеру.</p> </div> <button> <span class="emoji" aria-hidden="true">👊</span> <span class="text">Передать привет</span> </button> Скопировать
Интерактивным элементам нужны имена
У всех интерактивных элементов должны быть доступные имена. Они подробнее раскрывают цель элемента. Скринридеры объявляет их перед ролью.
Имена задаются двумя способами:
- с помощью HTML — текстовое содержимое тегов и атрибутов
altиtitle; - с помощью ARIA-атрибутов
aria-labelиaria-labelledby.
<!-- Неправильно ⛔ --> <button> <img src="logo.svg" alt=""> </button> <!-- Правильно ✅ --> <button> <img src="logo.svg" alt="Твиттер"> </button> <button aria-label="Твиттер"> <img src="logo.svg" alt=""> </button>