Доступность интерфейса — это не только вопрос визуального дизайна. Современный сайт должен быть понятен и удобен для людей, которые используют скринридеры, клавиатурную навигацию и другие вспомогательные технологии. Один из инструментов, который помогает сделать сложные интерфейсы доступнее, — ARIA (Accessible Rich Internet Applications).
В этой статье разберём, что такое ARIA-роли, когда они действительно нужны и как применять их на практике без типичных ошибок.
Что такое ARIA
ARIA — набор атрибутов HTML, предназначенных для описания семантики элементов интерфейса вспомогательным технологиям.
Например, визуально кнопка может быть реализована с помощью <div>. Для пользователя мыши она будет выглядеть и работать как кнопка, но скринридер не обязательно распознает её как интерактивный элемент.
ARIA позволяет дополнить информацию об элементе:
<div role="button" tabindex="0">
Открыть меню
</div>
Атрибут role="button" сообщает вспомогательной технологии, что элемент должен восприниматься как кнопка.
Однако здесь есть важный нюанс: ARIA не добавляет элементу поведение. Такой <div> не становится автоматически доступной кнопкой — разработчику всё равно нужно реализовать обработку клавиатуры, фокус и другие необходимые механизмы.
Поэтому главное правило звучит так:
Сначала используйте нативный HTML, а ARIA добавляйте там, где стандартной семантики недостаточно.
Что такое ARIA-role
role определяет семантическую роль элемента — то есть объясняет вспомогательной технологии, что это за объект.
Например:
<div role="navigation">
...
</div>
сообщает, что блок является областью навигации.
На практике используются разные категории ролей:
button— кнопка;navigation— навигационный блок;dialog— диалоговое окно;alert— важное сообщение, которое должно быть объявлено пользователю;tab— вкладка;tabpanel— содержимое вкладки;checkbox— флажок;menu— меню;tooltip— всплывающая подсказка;progressbar— индикатор выполнения.
Но выбор роли зависит не только от внешнего вида компонента. Нужно учитывать его назначение, поведение и взаимодействие с пользователем.
Когда ARIA действительно нужна
Хороший пример — модальное окно.
В HTML нет отдельного универсального элемента, который полностью описывает сложный компонент диалога во всех вариантах реализации. В таком случае ARIA помогает сообщить скринридеру о назначении интерфейса:
<div
role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
>
<h2 id="dialog-title">Удалить проект?</h2>
<p>Это действие нельзя отменить.</p>
<button>Удалить</button>
<button>Отмена</button>
</div>
Здесь используются сразу несколько механизмов:
role="dialog"определяет тип компонента;aria-modal="true"сообщает, что диалог является модальным;aria-labelledbyсвязывает окно с его заголовком.
Но одной разметки недостаточно. При открытии модального окна необходимо корректно управлять фокусом: перевести его внутрь диалога, обеспечить клавиатурную навигацию и вернуть фокус на исходный элемент после закрытия.
ARIA и нативный HTML
Одна из самых распространённых ошибок — использовать ARIA там, где уже существует подходящий HTML-элемент.
Например, вместо:
<div role="button">Отправить</div>
лучше написать:
<button type="submit">Отправить</button>
Нативная кнопка уже обладает необходимой семантикой и поддерживает стандартное взаимодействие с клавиатурой.
То же относится к другим элементам:
<nav>...</nav>
обычно предпочтительнее:
<div role="navigation">...</div>
А:
<button aria-expanded="false">
Категории
</button>
часто лучше, чем имитация кнопки на <div>.
Это делает код проще и одновременно уменьшает количество проблем с доступностью.
Часто используемые ARIA-атрибуты
ARIA — это не только role. Большое значение имеют атрибуты состояния и свойств.
aria-label
Задаёт доступное имя элемента, если его невозможно получить из видимого текста:
<button aria-label="Закрыть">
×
</button>
Это особенно полезно для кнопок с иконками.
При этом не стоит использовать aria-label без необходимости. Если у кнопки уже есть понятный текст, дополнительная метка обычно не нужна:
<button>Закрыть</button>
aria-labelledby
Связывает элемент с другим элементом, который содержит его название:
<section aria-labelledby="news-title">
<h2 id="news-title">Последние новости</h2>
...
</section>
aria-describedby
Используется для дополнительного описания:
<label for="email">Email</label>
<input
id="email"
type="email"
aria-describedby="email-help"
>
<p id="email-help">
Используйте рабочий адрес электронной почты.
</p>
Скринридер сможет связать поле с поясняющим текстом.
aria-expanded
Показывает, раскрыт ли связанный элемент:
<button
aria-expanded="false"
aria-controls="filters"
>
Фильтры
</button>
<div id="filters" hidden>
...
</div>
После открытия состояние должно измениться:
<button
aria-expanded="true"
aria-controls="filters"
>
Фильтры
</button>
Важно, чтобы ARIA-состояние соответствовало фактическому состоянию интерфейса.
aria-hidden
Позволяет исключить элемент из accessibility tree:
<span aria-hidden="true">★</span>
Например, декоративная иконка не должна дополнительно озвучиваться скринридером.
Но aria-hidden="true" нельзя бездумно применять к интерактивным элементам или их родителям: можно случайно скрыть от вспомогательной технологии содержимое, которое необходимо пользователю.
Пример: доступное раскрывающееся меню
Рассмотрим типичный компонент «Аккордеон»:
<button
type="button"
aria-expanded="false"
aria-controls="faq-answer-1"
>
Что такое ARIA?
</button>
<div id="faq-answer-1" hidden>
ARIA — набор атрибутов для повышения доступности веб-интерфейсов.
</div>
При нажатии JavaScript должен синхронно менять состояние:
button.addEventListener('click', () => {
const expanded = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!expanded));
answer.hidden = expanded;
});
Здесь ARIA отражает состояние компонента, а не просто добавляет декоративную информацию.
ARIA-роль для кастомных компонентов
На практике ARIA особенно полезна при создании сложных компонентов:
- вкладок;
- модальных окон;
- комбобоксов;
- кастомных списков;
- меню;
- деревьев;
- переключателей;
- drag-and-drop интерфейсов;
- динамических уведомлений.
Например, вкладки могут выглядеть следующим образом:
<div role="tablist" aria-label="Настройки профиля">
<button
role="tab"
aria-selected="true"
aria-controls="profile-panel"
id="profile-tab"
>
Профиль
</button>
<button
role="tab"
aria-selected="false"
aria-controls="security-panel"
id="security-tab"
>
Безопасность
</button>
</div>
<div
role="tabpanel"
id="profile-panel"
aria-labelledby="profile-tab"
>
...
</div>
Однако полноценная реализация вкладок требует не только ролей. Необходимо продумать перемещение фокуса, переключение с клавиатуры и изменение состояний aria-selected.
Главная ошибка: использовать ARIA вместо доступного поведения
Иногда разработчик добавляет:
<div role="button" tabindex="0">
Купить
</div>
и считает задачу решённой.
Но пользователь клавиатуры может ожидать, что кнопка будет реагировать на Enter и Space. Скринридер также должен получать корректное состояние элемента.
Если нет веской причины использовать <div>, лучше выбрать:
<button type="button">
Купить
</button>
Получится короче, понятнее и надёжнее.
Ещё несколько распространённых ошибок
Дублирование семантики
Не стоит писать:
<button role="button">Отправить</button>
У кнопки уже есть соответствующая семантика.
Неправильная роль
Роль должна соответствовать реальному поведению компонента. Нельзя выбирать role только потому, что название визуально кажется подходящим.
Несинхронизированные состояния
Если элемент открыт, но имеет:
aria-expanded="false"
вспомогательная технология получает неверную информацию.
Использование ARIA для декоративных элементов
Не каждый элемент интерфейса нуждается в ARIA. Лишние атрибуты могут усложнить accessibility tree и создать дополнительный шум.
Игнорирование клавиатуры
Доступность — это не только то, что «видит» скринридер. Интерактивные компоненты должны быть доступны с клавиатуры и иметь логичный порядок фокуса.
Как проверять ARIA на реальном проекте
После добавления ARIA недостаточно просто проверить HTML-код.
Полезно пройти несколько этапов:
- Проверить семантику HTML. Можно ли заменить кастомный компонент нативным элементом?
- Проверить клавиатурную навигацию. Можно ли добраться до элемента без мыши?
- Проверить фокус. Видно ли, где находится фокус и логично ли он перемещается?
- Проверить состояния. Соответствуют ли
aria-expanded,aria-selected,aria-checkedи другие атрибуты реальному состоянию? - Использовать автоматические аудиторы. Они помогают обнаружить часть распространённых проблем.
- Проверить интерфейс со скринридером. Это особенно важно для сложных компонентов.
Автоматические инструменты полезны, но не заменяют ручное тестирование: программа может обнаружить неправильный атрибут, но не всегда способна определить, насколько логично пользователь проходит сценарий.
Практический чек-лист для разработчика
Перед релизом компонента стоит задать несколько вопросов:
- Есть ли подходящий нативный HTML-элемент?
- Действительно ли здесь необходима ARIA?
- Правильно ли выбрана роль?
- Есть ли у элемента доступное имя?
- Соответствуют ли ARIA-атрибуты реальному состоянию?
- Можно ли пользоваться компонентом с клавиатуры?
- Логично ли перемещается фокус?
- Не скрывает ли
aria-hiddenважный контент? - Корректно ли компонент работает со скринридером?
- Проверен ли компонент не только автоматически, но и вручную?
Итог
ARIA — мощный инструмент, но использовать его нужно осознанно. Главная задача разработчика — не «добавить побольше ARIA», а обеспечить корректную семантику, поведение и взаимодействие.
Оптимальная последовательность выглядит так:
нативный HTML → корректное поведение → клавиатурная доступность → ARIA при необходимости → тестирование.
Если компонент можно сделать доступным с помощью обычных HTML-элементов, это обычно лучший вариант. ARIA стоит применять тогда, когда стандартной семантики действительно недостаточно.
Для веб-студии такой подход особенно важен: доступность должна закладываться не в конце разработки как отдельная доработка, а учитываться на этапе проектирования компонентов, дизайна и фронтенд-разработки. Это позволяет создавать интерфейсы, которые одинаково предсказуемо работают для максимально широкого круга пользователей.



