Перейти к содержанию
Innovialabs

ARIA-атрибуты: когда и как их использовать

Практика3 мин

Коротко

ARIA сообщает вспомогательным технологиям роль, имя и состояние элемента, но не добавляет поведения; используйте её только там, где нет подходящего нативного HTML-элемента.

Что такое ARIA и главное правило

ARIA (Accessible Rich Internet Applications) — набор HTML-атрибутов, которые объясняют экранным дикторам, что за элемент перед ними и в каком он состоянии. ARIA меняет только то, как элемент описывается в дереве доступности. Она не добавляет поведения: не делает элемент фокусируемым и не обрабатывает клавиши.

Первое правило ARIA: если есть нативный HTML-элемент с нужной семантикой и поведением — используйте его, а не ARIA.

<!-- Плохо: нужно вручную добавлять tabindex, Enter, пробел -->
<div role="button" onclick="save()">Сохранить</div>

<!-- Хорошо: всё уже встроено -->
<button type="button" onclick="save()">Сохранить</button>

Неправильная ARIA хуже, чем её отсутствие: она может сообщить диктору неверную информацию.

Три вида атрибутов

ВидЧто описываетПримеры
Роли (roles)Чем является элементrole="dialog", role="tab", role="alert"
Свойства (properties)Постоянные характеристики и связиaria-label, aria-labelledby, aria-describedby, aria-controls
Состояния (states)То, что меняется при взаимодействииaria-expanded, aria-selected, aria-checked, aria-hidden

Состояния нужно обновлять из JavaScript при каждом изменении интерфейса — иначе диктор будет сообщать устаревшие данные.

Самые полезные атрибуты

  • aria-label — даёт имя элементу без видимого текста, например кнопке с иконкой.
  • aria-labelledby — берёт имя из другого элемента по id, например заголовок модального окна.
  • aria-describedby — добавляет пояснение: подсказку или текст ошибки.
  • aria-expanded — раскрыт ли связанный блок: аккордеон, выпадающее меню.
  • aria-hidden="true" — скрывает элемент от диктора. Никогда не ставьте его на фокусируемые элементы.
  • aria-current="page" — отмечает текущую страницу в навигации.

Паттерн: модальное окно

Сегодня проще всего взять нативный <dialog> и открывать его через showModal(): браузер сам делает фон неактивным и закрывает окно по Esc.

<dialog aria-labelledby="dlg-title">
  <h2 id="dlg-title">Удалить проект?</h2>
  <p>Действие нельзя отменить.</p>
  <button type="button">Отмена</button>
  <button type="button">Удалить</button>
</dialog>

Если окно своё, на div: role="dialog", aria-modal="true", aria-labelledby, перевод фокуса внутрь при открытии, удержание фокуса, закрытие по Esc и возврат фокуса на кнопку-открыватель.

Паттерн: вкладки

<div role="tablist" aria-label="Тарифы">
  <button role="tab" id="t1" aria-selected="true" aria-controls="p1">Месяц</button>
  <button role="tab" id="t2" aria-selected="false" aria-controls="p2" tabindex="-1">Год</button>
</div>
<div role="tabpanel" id="p1" aria-labelledby="t1">…</div>
<div role="tabpanel" id="p2" aria-labelledby="t2" hidden>…</div>

Поведение с клавиатуры: Tab переводит фокус на активную вкладку и дальше в панель, стрелки переключают вкладки. При переключении обновляйте aria-selected и tabindex.

Паттерн: меню и выпадающие списки

Частая ошибка — ставить role="menu" на обычную навигацию сайта. Роль menu предназначена для меню приложения в стиле десктопных программ и требует управления стрелками. Для навигации и простого раскрывающегося списка ссылок достаточно:

<button type="button" aria-expanded="false" aria-controls="nav-list">Услуги</button>
<ul id="nav-list" hidden>
  <li><a href="/web">Сайты</a></li>
  <li><a href="/mobile">Приложения</a></li>
</ul>

При открытии меняйте aria-expanded на true и убирайте hidden.

Паттерн: live-регионы

Live-регион сообщает диктору об изменениях, которые происходят без перехода фокуса: «Товар добавлен в корзину», «Сохранено», ошибки отправки формы.

<div aria-live="polite" id="status"></div>
  • aria-live="polite" — диктор дочитает текущую фразу и затем озвучит изменение. Подходит почти всегда.
  • role="alert" (соответствует assertive) — прерывает речь. Только для срочных ошибок.
  • Регион должен существовать в DOM заранее, а меняться должен его текст. Элемент, добавленный вместе с текстом, часто не озвучивается.

Частые ошибки

  • aria-label на div или span без роли — многие дикторы его игнорируют.
  • aria-hidden="true" на контейнере, внутри которого есть кнопки.
  • Роль без поведения: role="button" без обработки клавиш.
  • Состояния не обновляются: aria-expanded="false" у открытого меню.
  • Дублирование: <button aria-label="Кнопка Отправить">Отправить</button> — имя должно совпадать с видимым текстом.

Полные паттерны с клавиатурным поведением описаны в ARIA Authoring Practices Guide.

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

Фреймворк не меняет правил. Используйте нативные элементы, а для сложных виджетов — проверенные библиотеки компонентов с поддержкой доступности или паттерны из APG.

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.