ARIA (полностью WAI-ARIA, Accessible Rich Internet Applications) – спецификация Web Accessibility Initiative, инициативы W3C по веб-доступности. Она появилась как ответ на эпоху динамических интерфейсов: вкладки, аккордеоны, модальные окна и автодополнение собираются из div и span, у которых нет встроенного смысла. ARIA добавляет этот смысл прямо в разметку: атрибут role описывает, чем элемент является, атрибуты aria-* – его свойства и текущее состояние. Скринридер благодаря им объявляет не безликий «текст», а «кнопка, свёрнуто» или «прогресс 75%». По формулировке W3C, спецификация задаёт «онтологию ролей, состояний и свойств» и дополняет нативную семантику HTML, а не заменяет её.
Как это работает
Ключевой принцип: ARIA – это no-op для всего, кроме доступности. Атрибуты не меняют DOM, внешний вид и поведение элемента. Меняется только его представление в accessibility tree – параллельной структуре, которую браузер передаёт вспомогательным технологиям через accessibility API операционной системы. Стили, фокус, обработку клавиатуры и логику на JavaScript разработчик реализует сам: ARIA лишь обещает пользователю определённое поведение, а выполнить обещание – задача кода. Все атрибуты стандарта делятся на три категории:
| Категория | Что описывает | Примеры |
|---|---|---|
| Роли (roles) | Чем элемент является для пользователя | role="button", role="progressbar", role="navigation" |
| Свойства (properties) | Относительно постоянные характеристики и связи | aria-label, aria-labelledby, aria-controls |
| Состояния (states) | Значения, меняющиеся по ходу работы интерфейса | aria-expanded, aria-checked, aria-current |
Актуальная версия – WAI-ARIA 1.2, рекомендация W3C с 6 июня 2023 года. WAI-ARIA 1.3 пока остаётся рабочим черновиком (редакция от 4 июня 2026 года): в нём готовятся роли sectionheader и sectionfooter и запрет aria-hidden="true" на корневом элементе документа. Спецификация описывает более 80 ролей, разбитых на шесть категорий: abstract (служебные, авторам использовать запрещено), widget, document structure, landmark, live region и window.
Landmark-роли и их HTML-эквиваленты
Landmark-роли размечают крупные области страницы, между которыми пользователь скринридера перемещается быстрыми командами. Современный семантический HTML создаёт те же ориентиры автоматически:
| ARIA-роль | HTML-эквивалент |
|---|---|
| banner | header (верхнего уровня) |
| navigation | nav |
| main | main |
| complementary | aside |
| contentinfo | footer (верхнего уровня) |
| search | search |
| region | section с доступным именем |
| form | form |
Зачем это нужно
ARIA закрывает ситуации, где нативной семантики не хватает: кастомные виджеты (табы, деревья, комбобоксы), динамические уведомления через live regions, связи между элементами, которые не выразить тегами. В практике на Битрикс-проектах типичные кандидаты – мобильные меню, фильтры каталога и слайдеры: штатные шаблоны компонентов часто собирают их на div, и без ролей и состояний такие виджеты для скринридера просто не существуют как интерактивные элементы. При этом главный документ W3C о применении стандарта – «Using ARIA» – начинается с запрета: первое правило ARIA – не используй ARIA, если есть нативный HTML-элемент с нужной семантикой и поведением. Всего правил в документе четыре, а не пять, как часто пишут в блогах:
- Есть нативный элемент с нужной семантикой и поведением – используй его, а не div с ролью
- Не меняй нативную семантику без необходимости: не заголовок с role="tab", а div с ролью и заголовок внутри него
- Все интерактивные ARIA-контролы должны полностью управляться с клавиатуры, включая Enter и Space
- Не ставь role="presentation" и aria-hidden="true" на фокусируемые элементы
Причину осторожности сообщество доступности формулирует как «No ARIA is better than bad ARIA»: неверная роль или несинхронизированное состояние дезинформируют пользователя, у которого нет возможности перепроверить интерфейс глазами. По данным исследования WebAIM Million, которые приводит MDN, страницы с ARIA в среднем содержат больше ошибок доступности, чем страницы без него. На SEO атрибуты aria-* напрямую не влияют – поисковики опираются на семантический HTML; связь доступности с GEO и машиночитаемостью для LLM работает через ту же семантику, а не через сами атрибуты.
Пример
Классическая ошибка – role="button" на div. Роль сообщает скринридеру «кнопка», но не даёт ни фокуса, ни реакции на Enter и Space: пользователь клавиатуры слышит кнопку, которую невозможно нажать.
<!-- Скринридер объявит «кнопка», но Tab, Enter и Space не работают -->
<div role="button" onclick="save()">Сохранить</div>
<!-- Минимально корректный вариант на div -->
<div role="button" tabindex="0" onclick="save()"
onkeydown="if(event.key==='Enter'||event.key===' ')save()">Сохранить</div>
<!-- Правильно: то же самое даёт одна строка -->
<button onclick="save()">Сохранить</button>А вот легитимный сценарий, где ARIA действительно нужна, – кастомный аккордеон: состояние «раскрыто/свёрнуто» передаёт атрибут aria-expanded, который JavaScript обязан переключать при каждом клике:
<button aria-expanded="false" aria-controls="panel1">Раскрыть раздел</button>
<div id="panel1" hidden>…</div>
<!-- JS при клике меняет aria-expanded на "true" и снимает hidden -->Скринридер объявит кнопку как «раскрыто» или «свёрнуто» – но только если скрипт действительно обновляет значение. Забытая синхронизация состояния – вторая по частоте проблема после ролей без клавиатуры: например, aria-current в меню, которое не обновляется при переходе между страницами, вредит навигации не меньше, чем его отсутствие.