Cегодня я хочу рассказать про атрибут 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 вызываю режим отображения списка кнопок на странице.



Отображается список из 1 кнопки
Отображается список из 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>

Проверю, как скринридер распознает её.


Отображается список из 1 кнопки
Отображается список из 1 кнопки

«Закрыть карточку товара, кнопка». Вот это уже другое дело.


Предыдущий пример с разметкой интерактивного элемента — не единственный практический кейс, где мы можем использовать атрибут aria-label. Часто в интерфейсах используется несколько областей навигации. Обычно это: «Основная навигация», «Хлебные крошки» и «Пользовательская навигация».


<nav>
  <!-- область основной навигации -->
</nav>

<nav>
  <!-- область хлебных крошек -->
</nav>

<nav>
  <!-- область пользовательской навигации -->
</nav>

Мысленно удалим комментарии и попробуем понять, где основная навигация? Да, чёрт знает, где она. Там просто 3 области. Основная навигация может быть в любой из них. Для скринридеров это также просто 3 области. Им также непонятно, какая область за что отвечает. Вот так JAWS видит страницу в режиме «Список областей»:


Отображается список из 3 областей навигации
Отображается список из 3 областей навигации

Как я говорил, скринридер JAWS видит 3 области навигации и всё. Какая из них какая, он не понимает.


Чтобы убедиться в этом, мы можем переключаться по странице с помощью клавиш со стрелкой вниз () и вверх (). Если мы нажимаем клавишу , то скринридер опускается вниз по странице, а если клавишу , то вверх.


Когда я нажимаю клавишу на нашей странице, скринридер JAWS попадает в первую область навигации (Основная) и говорит: «Область навигации». Далее он озвучивает внутренние элементы. А когда покидает область, то говорит: «Конец области навигации».


Ещё раз жму клавишу и слышу: «Область навигации». Это скринридер JAWS попал в область второй навигации, а именно в хлебные крошки. Но он не понимает этого, поэтому говорит точно такой же текст. Когда я покидаю область, то снова слышу «Конец область навигации», как в первый раз. С третьей областью будет точно так же.


Как улучшить данный опыт? Вот здесь атрибут aria-label очень полезен. С помощью него мы можем рассказать о назначении области. На примере областей навигации добавлю 3 подсказки:

<nav aria-label="Основная">
  <!-- элементы основной навигации -->
</nav>

<nav aria-label="Хлебные крошки">
  <!-- область хлебных крошек -->
</nav>

<nav aria-label="Пользовательская">
  <!-- элементы пользовательской навигации -->
</nav>

В этом случае скринридер JAWS видит 3 разных области навигации, а именно: основная, хлебные крошки и пользовательская.



Отображается список из 3 областей навигации
Отображается список из 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-канала 💰