В прошлом месяце я рассказал, зачем нужна семантика, на примере атрибута role
. Если вы не читали мою статью, пожалуйста, прочтите её перед тем, как читать эту. А сегодня я хочу рассказать про атрибут aria-label
. В статье не будет заумных определений и бездумного копирования стандарта. Я хотел простым языком объяснить, какая польза от атрибута, а также передать свой практический опыт, чтобы вы могли его повторить. А получилось у меня или нет, решать вам.
Со вступительным словом всё. Давайте начнём!
▍ Что это такое?
Каждый всплывающий элемент содержит кнопку, с помощью которой мы можем его закрыть. Мы с вами привыкли видеть её в виде иконки «крестик», как на следующем изображении:
Всплывающее окно на сайте Сбермаркет. На изображении выделена кнопка «Закрыть» в виде крестика
А как же пользователи скринридеров смогут посмотреть на неё? Вот здесь задача разработчика помочь им, а сделать это можно при помощи атрибута aria-label
.
aria-label
— атрибут, который позволяет разработчикам добавить текстовую подсказку к элементу, с помощью которой пользователи скринридера поймут его назначение.
Если проводить аналогию с доступностью в физическом мире, то атрибут aria-label
, как собака-поводырь и брайлевская табличка в одном, помогает незрячему человеку понять информацию о мире. Как пройти в столовую. Когда придёт автобус. Сколько стоит чашка кофе. Абсолютно любую информацию. Как это происходит, посмотрим на практике.
▍ Как атрибут помогает на практике
В качестве первого примера я буду использовать кнопку «Закрыть» на сайте СберМаркет:
Всплывающее окно на сайте Сбермаркет. На изображении выделена кнопка «Закрыть» в виде крестика
Представим, что нам нужно реализовать её доступность, и начнём мы с разметки:
<button type="button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path d="M7.707 6.293a1 1 0 0 0-1.414 1.414L10.586 12l-4.293 4.293a1 1 0 1 0 1.414 1.414L12 13.414l4.293 4.293a1 1 0 0 0 1.414-1.414L13.414 12l4.293-4.293a1 1 0 0 0-1.414-1.414L12 10.586 7.707 6.293Z"/>
</svg>
</button>
Для тестирования я открою страницу с помощью скринридера JAWS. Далее с помощью клавиш CTRL+INSERT+B
вызываю режим отображения списка кнопок на странице.
JAWS отображает список из 1 кнопки
Скринридер JAWS видит одну кнопку без метки. Если он будет озвучивать её, то мы услышим: «Без метки, кнопка». Мне непонятно, что делает кнопка. Нужно добавить подсказку с помощью атрибута aria-label
. Например, буду использовать подсказку «Закрыть карточку товара».
<button type="button" aria-label="Закрыть карточку товара">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path d="M7.707 6.293a1 1 0 0 0-1.414 1.414L10.586 12l-4.293 4.293a1 1 0 1 0 1.414 1.414L12 13.414l4.293 4.293a1 1 0 0 0 1.414-1.414L13.414 12l4.293-4.293a1 1 0 0 0-1.414-1.414L12 10.586 7.707 6.293Z"/>
</svg>
</button>
Проверю, как скринридер распознает её.
JAWS отображает список из 1 кнопки
«Закрыть карточку товара, кнопка». Вот это уже другое дело.
Предыдущий пример с разметкой интерактивного элемента — не единственный практический кейс, где мы можем использовать атрибут aria-label
. Часто в интерфейсах используется несколько областей навигации. Обычно это: «Основная навигация», «Хлебные крошки» и «Пользовательская навигация».
<nav>
<!-- область основной навигации -->
</nav>
<nav>
<!-- область хлебных крошек -->
</nav>
<nav>
<!-- область пользовательской навигации -->
</nav>
Мысленно удалим комментарии и попробуем понять, где основная навигация? Да, чёрт знает, где она. Там просто 3 области. Основная навигация может быть в любой из них. Для скринридеров это также просто 3 области. Им также непонятно, какая область за что отвечает. Вот так JAWS видит страницу в режиме «Список областей»:
JAWS отображает список из 3 областей навигации
Как я говорил, скринридер JAWS видит 3 области навигации и всё. Какая из них какая, он не понимает.
Чтобы убедиться в этом, мы можем переключаться по странице с помощью клавиш ↓
и ↑
. Если мы нажимаем клавишу ↓
, то скринридер опускается вниз по странице, а если клавишу ↑
, то вверх.
Когда я нажимаю клавишу ↓
на нашей странице, скринридер JAWS попадает в первую область навигации (Основная) и говорит: «Область навигации». Далее он озвучивает внутренние элементы. А когда покидает область, то говорит: «Конец области навигации».
Ещё раз жму клавишу ↓
и слышу: «Область навигации». Это скринридер JAWS попал в область второй навигации, а именно в хлебные крошки. Но он не понимает этого, поэтому говорит точно такой же текст. Когда я покидаю область, то снова слышу «Конец область навигации», как в первый раз. С третьей областью будет точно так же.
Как улучшить данный опыт? Вот здесь атрибут aria-label
очень полезен. С помощью него мы можем рассказать о назначении области. На примере областей навигации добавлю 3 подсказки:
<nav aria-label="Основная">
<!-- элементы основной навигации -->
</nav>
<nav aria-label="Хлебные крошки">
<!-- область хлебных крошек -->
</nav>
<nav aria-label="Пользовательская">
<!-- элементы пользовательской навигации -->
</nav>
В этом случае скринридер JAWS видит 3 разных области навигации, а именно: основная, хлебные крошки и пользовательская.
JAWS отображает список из 3 областей навигации
При переключении с помощью клавиши ↓
он также по-разному озвучивает их. В случае основной области навигации я слышу при входе: «Основная область навигации». А при выходе из неё: «Основная конец область навигации». В области хлебных крошек — «Хлебные крошки область навигации» и «Хлебные крошки конец область навигации». В области пользовательской навигации он скажет: «Пользовательская область навигации» и «Пользовательская конец область навигации».
▍ Особенности использования
Когда я начал использовать атрибут aria-label
, то добавлял его везде, где только мог. В один из таких моментов я определил его для элемента div
.
<div class="technologies" aria-label="Мои навыки">
<ul class="technologies__list">
<li class="technologies__group">
<span class="technologies__point">HTML</span>
</li>
<li class="technologies__group">
<span class="technologies__point">CSS</span>
</li>
<li class="technologies__group">
<span class="technologies__point">JS</span>
</li>
</ul>
</div>
Я ничего не подозревал, думая, что скринридер озвучит «Мои навыки», а дальше список из них. Когда я начал тестировать, то JAWS не прочитал подсказку из атрибута aria-label
, а сразу озвучивал список.
Погуглив, я нашёл, что для корректной озвучки атрибута существуют несколько правил использования. В стандарте Accessible Rich Internet Applications (WAI-ARIA) 1.2 сказано, что атрибут будет работать со всеми HTML-элементами, кроме следующих:
<caption>
-
<code>
<dd>
<dt>
<dfn>
<del>
<em>
<ins>
<mark>
<p>
<strong>
<sub>
<sup>
<time>
<span>
<div>
Также нельзя использовать атрибут для элемента, у которого установлен атрибут role
со следующими значениями:
role="caption"
role="code"
role="definition"
role="term"
role="deletion"
role="emphasis"
role="insertion"
role="mark"
role="paragraph"
role="strong"
role="subscript"
role="superscript"
role="time"
role="generic"
role="presentation"
role="generic"
role="none"
role="suggestion"
Таким образом, используемый мною элемент div
есть в списке запрещённых элементов, поэтому JAWS его проигнорировал.
▍ Как писать подсказки
Текстовая подсказка должна быть понятна как можно более широкому кругу людей, потому что если это будет не так, то человек со скринридером запутается и не сможет взаимодействовать с интерфейсом. Я для себя создал несколько правил, которыми хочу поделиться.
Первое звучит так: «Не стоит писать подсказки на основе внешнего отображения элемента». Вернёмся к предыдущему примеру с кнопкой «Закрыть».
Всплывающее окно на сайте Сбермаркет. На изображении выделена кнопка закрыть в виде крестика
Можно написать подсказку на основе того, как выглядит кнопка.
<button type="button" aria-label="Крестик">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path d="M7.707 6.293a1 1 0 0 0-1.414 1.414L10.586 12l-4.293 4.293a1 1 0 1 0 1.414 1.414L12 13.414l4.293 4.293a1 1 0 0 0 1.414-1.414L13.414 12l4.293-4.293a1 1 0 0 0-1.414-1.414L12 10.586 7.707 6.293Z"/>
</svg>
</button>
Скринридеры озвучат «Крестик, кнопка». Чем плоха такая подсказка? Во-первых, непонятно, что закрывает кнопка. Во-вторых, такая подсказка требует от пользователя определённый опыт, когда он уже раньше встречал такие кнопки. А если он столкнулся первый раз? Для него элемент станет ребусом.
Что делать в такой ситуации? Для кнопок я чаще всего использую формулу: «глагол + контекст». Чтобы подобрать глагол, я задаю себе вопрос: «Что делает кнопка?». Контекст беру из окружения элемента. Покажу на примере кнопки «Закрыть» на Сбермаркете.
Что делает кнопка? Закрывает. Где находится кнопка? В карточке товара. Получается, можно создать подсказку: «Закрыть карточку товара».
<button type="button" aria-label="Закрыть карточку товара">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path d="M7.707 6.293a1 1 0 0 0-1.414 1.414L10.586 12l-4.293 4.293a1 1 0 1 0 1.414 1.414L12 13.414l4.293 4.293a1 1 0 0 0 1.414-1.414L13.414 12l4.293-4.293a1 1 0 0 0-1.414-1.414L12 10.586 7.707 6.293Z"/>
</svg>
</button>
Второе правило: «Не использовать слова, которые явно указывают тип элемента». Часто разработчики от желания помочь дополнительно выделяют в подсказке тип элемента. Возвращаясь к примеру с подсказкой для области навигации, они бы использовали подсказку «Основная навигация».
<nav aria-label="Основная навинация">
<!-- элементы основной навигации -->
</nav>
Что скажет скринридер: «Основная навигация, навигация». Разработчики забыли, что скринридер самостоятельно озвучивает тип элемента. Оттого, что они захотели детализировать элемент словом «навигация» получилось дублирование. Оно жутко мешает пользователям. Так делать нельзя. Поэтому убираем слово «навигация» и оставляем «Основная»:
<nav aria-label="Основная">
<!-- элементы основной навигации -->
</nav>
Рассмотрим ещё один пример излишней детализации на примере ссылки «Выйти»:
<a href="/logout" aria-label="Кнопка выйти">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path d="M24 20v-4h-10v-4h10v-4l6 6zM22 18v8h-10v6l-12-6v-26h22v10h-2v-8h-16l8 4v18h8v-6z"/>
</svg>
</a>
Пользователи услышат «Кнопка выйти, ссылка». У незрячего пользователя сразу возникает вопрос: «Так это кнопка или ссылка?». Таким образом разработчики ввели их в замешательство. Какое решение? Не надо указывать тип элемента. Я видел много примеров, когда элемент сначала был кнопкой, потом его сделали ссылкой, а подсказку не изменили. Поэтому лучше не указывать такие детали.
<a href="/logout" aria-label="Выйти">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path d="M24 20v-4h-10v-4h10v-4l6 6zM22 18v8h-10v6l-12-6v-26h22v10h-2v-8h-16l8 4v18h8v-6z"/>
</svg>
</a>
▍ Заключение
Подводя итог, можно сказать, что атрибут aria-label
— важный друг для пользователя скринридера, с помощью которого мы можем рассказать ему больше об интерфейсе. Наши подсказки должны быть простыми для широкого круга пользователей и без лишних деталей о самом элементе. Важно помнить, что атрибут нельзя добавлять к некоторым элементам, в частности для элементов div
и span
.
Если у вас возникли вопросы, то я буду ждать вас в комментариях. Большое спасибо за уделённое время.
Узнавайте о новых акциях и промокодах первыми из нашего Telegram-канала ????
Комментарии (5)
vsh797
10.10.2023 09:20+3Хорошая статья, спасибо.
Как пользователь скринридера могу сказать, что главное свойство описания в aria-label — его наличие. Очень важно понимать, какой элемент на странице кликабельный, и что он делает. А "современный" подход делать такие элементы через span с onClick и иконкой внутри не дает никакой информации об этом. Сам на предыдущем проекте расставлял role="button" и aria-label на каждой странице, над которой работал. А иначе даже поставленную задачу не сделать.
По поводу aria-label у nav, единственное место, где я такое заметил — m.vk.com. Там прям так и есть
<nav role="navigation" aria-label="Основная">...</nav> <div class="mfoot" role="navigation" aria-label="Дополнительная">...</div>
Насколько необходимо каждый раз слышать "Основная" и "Дополнительная" перемещаясь по спискам на странице — дискуссионный вопрос. Здесь главное не пересолить. А вот на кнопках видеоплеера метки очень нужны.
amakhrov
10.10.2023 09:20+1Стоит упомянуть, что нет смысла добавлять
aria-label
на кнопку, у которой уже и так есть текстовое содержимое<button aria-label="Закрыть окно">Закрыть окно</button>
Здесь aria-label избыточен - если его нет, скринридер просто прочитает содержимое кнопки. В перспективе такое дублирование приведет к рассинхрону: поменяли текст в одном месте, оставили как было в другом
ifap
Здесь еще важно, как реализован код карточки товара, и как незрячий узнает, что зайдя на некую страницу ему в виде всплывающего окна суют еще и карточку товара, и закрывая ее он закрывает лишь спам, а не открытую страницу.
melnik909 Автор
Вы говорите о контексте. Да, важно уточнять его