Что делает aria-hidden=true с интерактивными элементами на самом деле
aria-hidden
в интерактивных элементах. Но в чём проблема? Я решил выяснить это, чтобы в следующий раз, когда об этом спросят, я мог лучше объяснить.Совсем недавно пришлось исправить один паттерн в системе дизайна, вызывавший множество ошибок, о которых сообщалось при автоматическом тестировании доступности. А именно — использование aria-hidden="true"
для интерактивных элементов (или их предков). Я помнил из своих тренингов и исследований, что такая комбинация плохо сказывается на доступности, поскольку элементы всё равно получают фокус при "табуляции" на них, даже если они намеренно скрыты от дерева доступности.
Чтобы лучше объяснить людям, которых я обучаю, решил поэкспериментировать, что ещё происходит в реальном мире, и написать об этом здесь.
Скринридеры ведут себя по-разному
До тестирования на скринридерах я бы предположил, что элементы с aria-hidden="true"
(на их предке или на них самих) будут полностью игнорироваться скринридерами. Я ожидал этого. Затем возникает вопрос: хорошо, а что, если мы используем скринридер и перемещаемся по странице с помощью Tab? Что тогда произойдёт?
Ну, это зависит (почти торговая марка). Опять — зависит от комбинации скринридера и браузера.
Я не тестировал все возможные комбинации и не тестировал разные версии, только последние, которые были под рукой, и вот результаты;
- NVDA и Chrome — при переходе Tab к интерактивным элементам они объявляются безымянными (то есть объявляются их роли, но не их имена). Такие интерактивные элементы недоступны в списке элементов и других ярлыках, поэтому практически невидимы.
- Narrator и Chrome vs. Edge — табуляция по элементам работала так же, как и с обычными интерактивными элементами (в основном игнорируя
aria-hidden="true"
), за исключением того, что Edge объявлял неверную роль для кнопки, но не для ссылки. Элементы не были доступны в ярлыках Narrator. - VoiceOver и Safari (iOS) — ничего не было объявлено, и все элементы были недоступны. Даже непосредственный тап по ним не срабатывал. В меню Rotor нет ни единого следа.
- TalkBack и Chrome (Android) — то же самое, что и с VoiceOver и Safari — ничего не объявлено, нигде нет следов.
Это были лишь возможные варианты, и на самом деле неважно, какие версии использовались, так как в любом случае вы никогда не должны использовать aria-hidden="true"
на родителях — или непосредственно на интерактивных элементах. Но я просто хотел проверить, какие последствия это имеет для пользователей скринридеров.
Это действительно выглядит запутанным, и мне кажется, что TalkBack и VoiceOver, полностью игнорирующие интерактивные элементы, жёстко соблюдают спецификацию, в то время как реализация NVDA и Narrator немного более свободна.
Учтите — эти тесты могут стать неактуальными в любой момент, поскольку всё может измениться, особенно для такого сценария, который не следует использовать в реальной жизни. Но я наверняка вспомню об этом эксперименте, когда в следующий раз буду объяснять, почему это плохо, и, надеюсь, вы тоже.
Код, использованный для тестирования:
<section aria-hidden="true">
<h3>parent with aria-hidden with a button and a link</h3>
<button type="button">Test button in a parent</button>
<a href="#">Test link in a parent</a>
</section>
<section>
<h3>Button and link that have aria-hidden attribute</h3>
<button type="button" aria-hidden="true">Independent button with aria-hidden</button>
<a href="#" aria-hidden="true">Independent link with aria-hidden</a>
</section>
Тестовая страница, если хотите опробовать сценарии.
Как решить эту проблему
В идеале следовало бы использовать CSS display:none;
или visibility:hidden;
или HTML атрибут hidden
, но это не вариант, так как хотелось, чтобы содержимое было как бы
видно (из-за необходимости анимации).
Я использовал — теперь уже хорошо поддерживаемый — HTML аттрибут inert
. Он решает все проблемы, которые не может решить aria-hidden="true"
;
- Контент со всеми дочерними элементами, включая интерактивные, по-прежнему отображается и виден.
- Вы больше не можете перемещаться табом к интерактивным элементам.
- Контент и интерактивные элементы удаляются из дерева доступности.
И снова полезная вещь для обучения людей — возможности, которые у нас есть, когда мы думаем о видимости, фокусе клавиатуры и доступности дерева воздействия.
Заключение — остерегайтесь aria-hidden=true
Я нечасто использую aria-hidden="true"
, даже для не интерактивных элементов, за исключением случаев, когда имеются дублирующие иконки (иконки, используемые в кнопке или ссылке, где также есть видимый текст). Последнее время я не использую aria-hidden="true"
для всего остального. Это может сбивать с толку, когда что-то скрывается для вспомогательных технологий (например, скринридеров), но при этом отображается визуально (некоторые пользователи скринридеров могут видеть экран).
В любом случае не используйте aria-hidden="true"
в интерактивных элементах или их родительских элементах — теперь вы знаете, почему (если раньше вы были настроены скептически).