Modern technology gives us many things.

Прокачиваем вёрстку ARIA-атрибутами. Атрибут role

67

Уровень сложности Средний Время на прочтение 8 мин Количество просмотров 2.6K Блог компании RUVDS.com Веб-разработка *CSS *HTML *Accessibility * Туториал

Прокачиваем вёрстку ARIA-атрибутами. Атрибут role

В разговорах людей, интересующихся доступностью, часто можно услышать слово «Роль». Так, что это такое? Это специальная форма представления элемента для скринридера. Устанавливается она с помощью атрибута role. Сегодня поговорим о нем.

Я не буду описывать всё. Атрибут слишком сложный для одной статьи. Остановлюсь на моментах, которые вы можете использовать сразу. Продвинутые техники оставим на другой случай.

Давайте начнём!

Что это такое?

Сегодня почти каждый фронтендер слышал фразы: «Семантическая вёрстка», «Семантика». Эти слова в сознании разработчика закрепились как что-то полезное и правильное. Это, безусловно, так. Семантика — единственный способ донести смысл HTML страницы до браузеров, скринридеров и других технологий.

Стандарт WAI-ARIA привнёс новый взгляд на семантику, добавив атрибут role. Он супергерой со сверхспособностью. Она заключается в том, что атрибут управляет семантикой. Или проще говоря, он говорит скринридеру, какой элемент перед ним.

Рассмотрим пример, в котором я создал заголовок первого уровня.

<body> <h1>Будьте внимательны с этим примером</h1> </body>

В результате скринридер скажет: «Заголовок первого уровня. Будьте внимательны с этим примером». Теперь добавим role=»link» к элементу <h1>.

<body> <h1 role=»link»>Будьте внимательны с этим примером</h1> </body>

Теперь скринридер скажет: «Ссылка. Будьте внимательны с этим примером». Магия! Фактически мы сделали из заголовка ссылку, не меняя HTML элемент. И это не всё.

Он может сделать вообще полную анархию. Значения presentation и none удаляют семантику элемента, оставляя видимым для скринридеров только его контент.

Для примера я сделал так, чтобы элемент <h1> перестал быть заголовком первого уровня, но текст внутри озвучивался.

<body> <h1 role=»presentation»>Будьте внимательны с этим примером</h1> </body>

Скринридер скажет: «Будьте внимательны с этим примером». Всё. Никакого «Заголовок первого уровня», не «Ссылка». Ничего. Обычный текст. Как будто он был вставлен в элемент <body> без HTML элемента.

Важно заметить, что такие трансформации происходят только для скринридеров. Например, для поисковых движков элемент во всех случаях остаётся заголовком первого уровня.

При первом взгляде мне атрибут показался бесполезным. Это случилось из-за отсутствия опыта. Конечно, я сильно ошибался. Теперь я набрался знаний и спешу поделиться своим опытом. Перейдём к практике!

Используем на практике

Перед тем, как я поделюсь ситуациями, где полезно определять значения для атрибута role, у меня есть важное сообщение. Стандарт и сообщество экспертов не рекомендует делать это. Сначала нужно использовать правильно HTML элементы.

В любом правиле есть исключения. В этом тоже. В конечном счёте наша задача заключается в предоставлении хорошего опыта от взаимодействия с интерфейсом для пользователей. А не в слепом следовании стандартам. Поэтому если что-то меняете, то убедитесь, что везде работает одинаково хорошо. А теперь к практике.

Читать на TechLife:  Производство карт «Тройка» стало полностью российским

Первой ситуацией использования атрибута role связано с нехваткой стандартных возможностей HTML. Например, как можно разметить форму поиска? Для начала нужно использовать элемент <form>.

<body> <form> <!— здесь дочерние элементы формы поиска —> </form> </body>

Да, скринридеры увидят форму. Только как они догадаются, что перед ними поиск? В стандарте WHATWG HTML есть элемент <search>. Он поможет, если элемент <form> обвернуть им.

Правда до конца 2023 года он не поддерживался браузерами, и мы не могли его использовать. Есть ещё варианты? Нет. В этой ситуации на помощь приходит стандарт WAI-ARIA 1.2. В нём есть специальное значение search для атрибута role, обозначающее область поиска.

Улучшу текущую разметку, добавив role=»search» к элементу <form>.

<body> <form role=»search»> <!— здесь дочерние элементы формы поиска —> </form> </body>

Таким нехитрым способом мы улучшили понимание скринридером нашей разметки. Пользователи смогут с помощью горячих клавиш перейти к поиску. Переходим к следующему примеру.

Всегда нужно помнить, что на работу скринридера также влияет CSS. Да, ещё делает это так, что не всегда это очевидно. Взять свойство list-style. Каждый раз, когда используется значение none, список потерян для скринридеров.

<body> <ul class=»list»> <li>Пункт 1</li> <li>Пункт 2</li> </ul> </body>
.list { list-style: none; }

Вернуть видимость списка поможет атрибут role со значением list.

<body> <ul role=»list» class=»list»> <li>Пункт 1</li> <li>Пункт 2</li> </ul> </body>

Всё. Мы вернули список на место. Скринридеры найдут его.

Особенности использования

▍Связь атрибута role и HTML элементов

Однажды я инспектировал код в DevTools и задумался: «А почему так получилось, что для элемента <button> применяется role=»button»?» Откуда браузеры это знают. Они же не телепаты!

Действительно, существует стандарт ARIA in HTML. В нём описано взаимоотношения ARIA атрибутов и HTML элементов. В частности есть таблица, где для каждого элемента указано значение атрибута role по умолчанию. Плюс также перечисленны все допустимые значения.

Например, вернёмся к случаю разметки формы поиска.

<body> <form> <!— здесь дочерние элементы формы поиска —> </form> </body>

В этом примере у нас есть элемент <body>. Согласно таблице для него по умолчанию определено значение generic. Далее я использую элемент <form>. У него уже определено значение form.

Поскольку элемент <form> вложен в элемент <body>, то эта структура сохранится для скринридеров. Только вместо HTML элементов они увидят, что в элемент со значением generic для атрибута role вложен элемент со значением form.

generic form

Похожие сообщения

После добавления role=»search» к элементу <form> встроенное значение form меняется на search. Теперь оно вложено в элемент со значением generic.

generic search

Любая страница в интернете будет выглядеть так для скринридера. В какой-то степени мы переходим на другой уровень абстракции. Но не стоит забывать о правилах самого языка HTML. Рассмотрим следующий пример:

<body> <p> <div role=»link» tabindex=»0″>Это уже ссылка?</div> </p> </body>

А здесь ошибка! Элемент <div> можно использоваться внутри элементов категорий «Flow content» или «Palpable content». А элемент <p> не относится к ним. Его категория — «Phrasing content». По этой причине браузеры трансформируют код. Они вынесут элемент <div> за пределы элемента <p>.

<body> <p></p> <div role=»link» tabindex=»0″>Это уже ссылка?</div> </body>

Следовательно, скринридеры уже увидят код также изменённым. Для них элемент со значением generic будет содержать два элемента. Первый со значением paragraph, взятого как значение по умолчанию для элемента <p>. Второй элемент с установленным значением link.

generic paragraph link

Вот так по невнимательности можно полностью запутать пользователя скринридера. Поэтому будьте внимательны. Следуйте всем правилам языка HTML.

▍Значение presentation

В начале статьи я сказал, что атрибут role позволяет нам скрыть элемент от скринридера с сохранением доступности его контента. Для этого в стандарте WAI-ARIA 1.2 есть значение presentation. Звучит вроде просто. На дело есть ряд важных особенностей, влияющие на работу значения. Рассмотрим каждую.

Первая заключается в том, что если элемент является интерактивным, браузеры вместе со скринридером должны игнорировать role=»presentation» и использовать встроенную семантику элемента. В следующем примере я попробовал удалить семантику элемента <button>.

<body> <button role=»presentation» type=»button»>Перейти</button> </body>

На практике этот пример будет обработан по разному. Например, самыми стабильными будут скринридеры JAWS и VoiceOver. Я протестировал пример в браузерах Google Chrome, Firefox, Edge и Safari при помощи клавиши Tab и ↓. Результат одинаковый. Элемент озвучивается так: «Перейти, кнопка».

А вот скринридер NVDA выдаёт целый букет вариантов. При взаимодействии клавишами Tab, и ↓ в браузерах Google Chrome и Edge скринридер скажет только контент элемента «Перейти». Что он является кнопкой, не будет озвучено. А в браузере Firefox озвучено будет всё. Контент элемента, и что он является кнопкой.

При первом столкновении с этой особенностью я подумал, что если убрать интерактивность атрибутом tabindex, то будет всё работать.

<body> <button role=»presentation» tabindex=»-1″ type=»button»>Перейти</button> </body>

Меня ждал очередной облом. Скринридеры продолжали работать без изменений. Что сказать. Не надо добавлять role=»presentation» для интерактивных элементов. И точка.

Следующим нюансом является объявление role=»presentation» для элемента, у которого определены глобальные ARIA-атрибуты. К ним относят атрибуты:

  • aria-label;
  • aria-braillelabel;
  • aria-labelledby;
  • aria-describedby;
  • aria-details;
  • aria-description;
  • aria-roledescription;
  • aria-brailleroledescription;
  • aria-hidden;
  • aria-flowto;
  • aria-keyshortcuts;
  • aria-current;
  • aria-controls;
  • aria-owns;
  • aria-live;
  • aria-busy;
  • aria-atomic;
  • aria-relevant.
Читать на TechLife:  Apple возвращается в Россию? Компания ищет специалиста со знанием русского языка и культуры

В этих ситуациях стандарт WAI-ARIA 1.2 говорит нам, что скринридер должен игнорировать role=»presentation». Посмотрим, как дело обстоит на практике.

Я создам заголовок третьего уровня, у которого установлен глобальный атрибут aria-describedby и объявлено role=»presentation».

<body> <h3 role=»presentation» aria-describedby=»description-of-heading»>Это заголовок или нет?</h3> </body>

Если используются скринридеры NVDA и VoiceOver в браузерах Google Chrome, Edge, Safari и Firefox, то всё происходит по плану. Пользователь услышит: «Заголовок уровня три. Это заголовок или нет?». А вот скринридер JAWS скажет так, только в Firefox. В Google Chrome и Edge будет озвучен только текст: «Это заголовок или нет?».

Таким образом мы получаем, что скринридеры NVDA и VoiceOver игнорируют role=»presentation» во всех браузерах. А скринридер JAWS делает так, только в Firefox.

Проведя больше экспериментов, с другими атрибутами, я обнаружил комбинации, при которых браузеры также работали нестабильно. К сожалению, я не нашёл причину такого поведения. Поэтому я посоветую, быть внимательными при объявлении role=»presentation» для элементов с установленными глобальными ARIA-атрибутами.

В стандарте WHATWG HTML есть группа элементов, у которых есть связь с дочерними элементами. Например, элементы <ul> или <table>. Если мы объявим role=»presentation» для родительского элемента, то его дочерние элементы также станут недоступны для скринридера.

<body> <ul role=»presentation»> <li>Для скринридеров это обычный текст</li> </ul> </body>

Они скажут: «Для скринридеров это обычный текст». А если в роли контента выступает HTML элемент, то он сохранит свою доступность. Как делает это ссылка в следующем примере:

<body> <ul role=»presentation»> <li><a href=»https://habr.com»>Хабр</a></li> </ul> </body>

Скринридеры скажут: «Ссылка. Хабр».

▍Значение none

Мы рассмотрели значение presentation. Оно существует с первых версий стандарта WAI-ARIA. К сожалению, наименование presentation сбивало с толку разработчиков. По этой причине авторам стандарта пришлось вводить новое значение none, которое, по их мнению, более понятно передаёт смысл.

В версии стандарта WAI-ARIA 1.2 сказано, что оно является синонимом значения presentation. Что лучше использовать? На момент написания статьи значение none ещё плохо поддерживается скринридерами. Но будущее за ним. В черновике стандарта авторы уже перенесли описание работы значения и примеры кода из раздела presentation в раздел none. Ждём, когда они опубликуют эту версию. Тогда уже можно будет использовать значение none.

Заключение

Подведём итог. Ключевые моменты при работе с атрибутом role:

  • Атрибут устанавливает или скрывает от скринридеров семантику элемента;
  • Для большинства HTML элементов есть значение по умолчанию;
  • При использовании значений presentation и none скринридер озвучит только контент элемента;
  • Есть строгие правила использования значений presentation и none.

Дополнительно вы можете посмотреть статьи:

  • Как улучшить вёрстку атрибутом aria-label
  • Как скрыть элемент от скринридера, используя атрибут aria-hidden

Если у вас возникли вопросы, то я буду ждать вас в комментариях. Большое спасибо за чтение.

Скидки, итоги розыгрышей и новости о спутнике RUVDS — в нашем Telegram-канале 🚀

Прокачиваем вёрстку ARIA-атрибутами. Атрибут role

Теги:

  • accessibility
  • html
  • css
  • ruvds_статьи

Хабы:

  • Блог компании RUVDS.com
  • Веб-разработка
  • CSS
  • HTML
  • Accessibility

Источник

Каталог товаров с купонами и промокодами онлайн

Оставьте ответ

Ваш электронный адрес не будет опубликован.

©Купоно-Мания.ру