ARIA-атрибуты в HTML: когда они действительно нужны

ARIA-атрибуты (role, aria-label, aria-hidden и другие) нужны не всегда - и первое правило доступности звучит именно так: если для нужного смысла уже есть готовый HTML-тег, используй его, а не role. ARIA - это заплатка для нестандартных виджетов из div и span, которым HTML не может дать смысл сам по себе, а не замена уже семантичным тегам.

Нажми Tab несколько раз внутри блокнота - фокус пройдёт и по настоящей кнопке, и по div с role="button" (у него есть tabindex="0"). Теперь удали tabindex="0" у div и попробуй снова - Tab будет проходить мимо неё, хотя роль "button" формально осталась.

Первое правило ARIA в HTML: не заменяй семантический тег атрибутом role

Первое правило ARIA дословно звучит так: если для нужного смысла и поведения уже есть родной HTML-тег - используй его, а не переделывай произвольный элемент через role. У тега button и роль "button", и обработка Enter/Space, и фокус по Tab уже встроены бесплатно. У div role="button" ничего этого нет по умолчанию: фокус и клавиатуру нужно добавлять вручную.

<button>Отправить</button> - роль, фокус и клавиатура работают сами, без единого дополнительного атрибута.

<div role="button">Отправить</div> - роль есть, но без tabindex элемент недоступен с клавиатуры, а Enter/Space придётся обрабатывать вручную через JS.

Из истории "Первое правило ARIA" дословно сформулировано в руководстве W3C "Using ARIA" - использовать родной HTML-тег вместо role, если это возможно. В том же документе есть раздел с говорящим названием "No ARIA is better than Bad ARIA" ("Отсутствие ARIA лучше плохой ARIA"). Ежегодный отчёт WebAIM Million, анализирующий миллион реальных сайтов, из года в год фиксирует контринтуитивный факт: страницы, использующие ARIA-атрибуты, в среднем содержат БОЛЬШЕ найденных ошибок доступности, чем страницы вообще без ARIA - неправильно применённая ARIA чаще вредит, чем помогает.

Когда ARIA-атрибуты в HTML действительно нужны: кастомные виджеты и иконки

ARIA нужна там, где родного тега для смысла просто нет: кастомные виджеты вроде выпадающего списка или вкладок, собранные из div, требуют role, aria-expanded, aria-selected. Кнопке без видимого текста (только иконка) нужен aria-label, чтобы у неё вообще было произносимое имя. А декоративную иконку рядом с текстом можно скрыть от скринридера через aria-hidden="true" - но ТОЛЬКО если элемент не может получить фокус: если поставить aria-hidden на ссылку или кнопку, пользователь скринридера долистает до неё Tab'ом, а она окажется невидимой и неозвученной.

<button aria-label="Закрыть"><span aria-hidden="true">&times;</span></button> - у кнопки есть произносимое имя, а декоративный символ скрыт от скринридера.

<a href="#" aria-hidden="true">Подробнее</a> - ссылка остаётся в фокусе по Tab, но для скринридера она как будто не существует: пользователь попадёт на невидимый, неозвученный элемент.

Частые ошибки новичков

ОшибкаЧто происходитКак исправить
Ставить role="button" на настоящий тег button Роль уже встроена в button по умолчанию - атрибут просто лишний Убрать role, тег и так объявляет нужную роль сам
Ставить role="button" на div без tabindex и обработки клавиш Элемент получает роль, но недоступен с клавиатуры - пользователь без мыши не сможет им воспользоваться Использовать настоящий button, либо вручную добавить tabindex="0" и обработку Enter/Space
Ставить aria-hidden="true" на элемент, который остаётся в фокусе (ссылка, кнопка) Пользователь скринридера дойдёт до него Tab'ом, но он окажется невидимым и неозвученным Не ставить aria-hidden на фокусируемые элементы - только на декоративный, нефокусируемый контент
Добавлять ARIA-атрибуты "на всякий случай" без проверки скринридером По данным WebAIM Million, неправильная ARIA чаще увеличивает число ошибок, а не снижает Проверять реальным скринридером, а не полагаться на то, что атрибут "выглядит правильно"

Шпаргалка

ТерминКогда использовать
Первое правило ARIAЕсть родной HTML-тег с нужным смыслом - используй его вместо role
role="button" на divНужно ещё вручную добавить tabindex="0" и обработку Enter/Space
aria-labelДаёт произносимое имя элементу без видимого текста (кнопка-иконка)
aria-hidden="true"Скрывает декоративный контент от скринридера - никогда на фокусируемых элементах
aria-liveОбъявляет скринридеру изменения контента без перезагрузки страницы

Коротко: отвечаем на вопросы

Когда использовать ARIA вместо обычного HTML?

Только когда для нужного смысла или поведения нет родного HTML-тега - например, для кастомного виджета вроде вкладок или выпадающего списка, собранного из div. Если подходящий тег есть (button, nav, main и так далее) - первое правило ARIA требует использовать именно его, а не патчить произвольный элемент через role.

Работает ли aria-label, если у элемента уже есть видимый текст?

Технически да, но aria-label ПОДМЕНЯЕТ то, что объявит скринридер, вместо видимого текста - если они разойдутся, это собьёт с толку пользователя, который слышит одно, а видит другое. Если видимый текст уже есть, обычно лучше не трогать имя элемента вообще или использовать aria-labelledby, который явно ссылается на этот текст.

Почему aria-hidden элемент всё ещё в фокусе или озвучивается?

Это реальная и задокументированная ошибка: aria-hidden на родительском элементе не забирает фокусируемость у вложенных ссылок и кнопок. В результате пользователь скринридера долистает до элемента Tab'ом, а тот окажется невидимым и неозвученным для него. Правило простое: aria-hidden ставится только на нефокусируемый, декоративный контент.

Нужен ли role="button" на теге button?

Нет. У button эта роль уже встроена по умолчанию - добавлять role="button" поверх неё не имеет смысла и ничего не меняет.

Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×