Подстраховка web-доступности семантических областей HTML5 через роли WAI-ARIA

  • Tutorial
Как известно, HTML5 имеет расширенные возможности семантической вёрстки. Он позволяет обернуть отдельные логические блоки страницы в специально предназначенные для них блочные теги, какие как header, main, footer и другие. Ну а улучшение структурной и семантической вёрстки, как правило, автоматически способствует повышению уровня accessibility web-интерфейса для пользователей программ экранного доступа, потому что они добавляют элементы страницы, по которым возможно осуществлять навигацию и быстро перемещаться между блоками контента.

В принципе, дополнительная разметка для обеспечения accessibility реализуется через отдельную технологию WAI-ARIA, однако и стандартные семантические структуры HTML5 современными браузерами и современными программами экранного доступа воспринимаются как соответствующие атрибуты ARIA для вспомогательных технологий. Проще говоря, это означает, что в теории следующие два варианта вёрстки с точки зрения программ чтения экрана аналогичны::

Листинг 1:

<!DOCTYPE html>
<html lang="ru">
	<head>
		<meta charset="utf-8">
		<title>Листинг 1</title>
		<!--[if lt IE 9]>
			<script type="text/javascript">
				var e = ("aside,footer,header,main,nav").split(',');
				for (var i = 0; i < e.length; i++) {
					document.createElement(e[i]);
				}
			</script>
		<![endif]-->
	</head>
	<body>
		<header>
			Верхний колонтитул
		</header>
		<aside>
			<nav>
				Навигационная панель
			</nav>
		</aside>
		<main>
			Основное содержимое
		</main>
		<footer>
			Нижний колонтитул
		</footer>
	</body>
</html>


Поскольку в рамках всей статьи нас интересует только то, что происходит в контейнере body, то далее договоримся, что в последующих листингах будет приводиться только вёрстка из body, а всё остальное будет подразумеваться как в листинге 1.)

Листинг 2:

		<div role="banner">
			Верхний колонтитул
		</div>
		<div role="complementary">
			<div role="navigation">
				Навигационная панель
			</div>
		</div>
		<div role="main">
			Основное содержимое
		</div>
		<div role="contentinfo">
			Нижний колонтитул
		</div>


Итак, листинг 1 свёрстан с использованием стандартных семантических возможностей HTML5, а листинг 2 использует старую добрую блочную вёрстку через div, но с добавлением разметки WAI-ARIA. По задумке разработчиков стандартов доступности, браузеров и вспомогательных технологий предполагается, что эти две страницы должны обрабатываться программами экранного доступа одинаково, однако тут мы и сталкиваемся с прозой жизни.

Возьмём две наиболее популярные программы экранного доступа: JAWS (версии 15.0) и NVDA (версии 2014.3), а также два наиболее популярных у их пользователей браузера: Internet Explorer (версии 11) и Firefox (версии 32). После этого протестируем все возможные конфигурации на предмет обработки семантических областей из листинга 1. В итоге, получим следующие результаты:

Поддержка семантических тегов HTML5
Теги JAWS
Internet Explorer
JAWS
Firefox
NVDA
Internet Explorer
NVDA
Firefox
aside Да Да Нет Да
footer Нет Да Нет Да
header Нет Да Нет Да
main Да Да Нет Да
nav Да Да Нет Да


Оказывается, что всё работает далеко не так, как предполагается теоретически. Причём с понижением версий ПО поддержка некоторых структур может начать неравномерно отваливаться. А главное в официальных руководствах и технических стандартах об этом вряд ли удастся прочитать, и такие проблемы сможет выявить лишь опытный и дотошный QA-инженер accessibility, который есть далеко не в каждом даже очень крупном проекте, пускай там доступность и прописана в ТЗ, например, в случае разработки социально ориентированных или государственных сайтов, а также в проектах, для которых доступность подразумевается как конкурентное преимущество, например, Интернет-банкинги. Про проекты не фокусированные на accessibility и говорить не приходится.

Разумеется, поскольку финальный вариант WAI-ARIA принят совсем недавно, а руководство по его поддержки со стороны User Agent вообще до сих пор не существует в завершённом виде, то в будущем, когда всё утрясётся, можно надеется, что и такие вещи также унифицируются. Однако проекты разрабатываются и сдаются уже здесь и сейчас, да и graceful degradation тоже никто ещё не отменял. Поэтому имеет смысл верстать так, чтобы с одной стороны использовать семантические новинки HTML5, а с другой — не обижать вспомогательные технологии при любых раскладах.

Достигнуть этого можно путём одновременного использования и семантики HTML5, и разметки WAI-ARIA. То есть к этим тегам надо будет добавлять соответствующие роли WAI-ARIA, как бы подстраховывая семантические области HTML5 через Accessible Rich Internet Applications.

Здесь следует сразу предупредить, что атрибуты разметки WAI-ARIA имеют более высокий приоритет, чем стандартные семантические структуры HTML5, поэтому если, например, для тега main прописать атрибут role со значением contentinfo, то программы экранного доступа будут называть его так, как будто это footer. Так что отсутствие WAI-ARIA лучше, чем наличие её некорректного применения. Иными словами: «Не умеешь, не берись», но эта статья как раз и призвана научить этому не сложному приёму вёрстки.

По большому счёту, всё сводится к необходимости выучить правильное соответствие ролей WAI-ARIA и стандартных семантических структур HTML5. В принципе, из листингов 1 и 2 основные соответствия уже ясны:

Соответствие базовых семантических тегов HTML5 и значений атрибута role из WAI-ARIA
Тег HTML5 Роль WAI-ARIA
footer contentinfo
header banner
main main
nav navigation


Кстати, что касается роли banner, специально оговоримся, что она предназначена для оборачивания именно всей шапки страницы, а не рекламного баннера. То есть она, действительно, прямой аналог тега header. Как показывает практика, некоторых слово «banner» вводит в заблуждение, и они начинают это значение присваивать именно рекламным баннерам, но это неправильно.

Вышеприведённые соответствия позволят корректно разметить в WAI-ARIA базовые семантические области HTML5. Однако заметно, что там упомянуты далеко не все из них. Дело в том, что во-первых, некоторые семантические структуры HTML5 не имеют прямых аналогов WAI-ARIA, например, это касается тега article, а во-вторых, с некоторыми из них всё не так просто, главным образом, речь, конечно, об aside.

По умолчанию тег aside программами экранного доступа трактуется как аналог роли complementary. В принципе, в большинстве случаев так и должно быть, однако диапазон возможного применения aside достаточно велик, поэтому могут встречаться ситуации, когда роль complementary будет не очень уместна.

Откровенно говоря, здесь мы уже вступаем на достаточно тонкий лёд вкусовщины и субъективного понимания дизайна невизуальных интерфейсов, где дискуссии примерно соответствуют спором о шрифтах или цветовых гаммах в мире визуальных интерфейсов. Тем не менее, всё же приведём один пример, чтобы дать представление об этом аспекте.

Листинг 3:

		<header role="banner">
			Верхний колонтитул
		</header>
		<aside role="complementary">
			<nav role="navigation">
				Навигационная панель
			</nav>
		</aside>
		<main role="main">
			Основное содержимое
			<aside role="note">
				Теги основного содержимого
			</aside>
		</main>
		<footer role="contentinfo">
			Нижний колонтитул
		</footer>


Роль complementary описывает для программ экранного доступа блок интерфейса как участок с некой дополнительной информацией, не имеющей прямого отношение к основному содержимому. Однако в нашем примере мы выделяем два таких блока: на уровне всей страницы, в который оборачиваем навигационную панель, а также внутри основного содержимого, куда оборачиваем теги. Очевидно, что по своей сути это сильно различающиеся блоки с дополнительной информацией, поэтому второму мы назначили роль note, которая маркерует блок как участок с неким примечанием.

Использование таких приёмов вёрстки требует уже несколько большего понимания логики невизуальных интерфейсов, поэтому рубить с плеча тут не стоит. Можно только посоветовать всё-таки использовать роль complementary, а более сложные интерфейсные ходы применять только если вы в достаточной степени уверены, что это уместно. Если бы в листинге 3 вместо note была использована complementary, то это было бы лучше, чем наоборот.

К слову, у роли note нет прямого аналога среди семантических тегов HTML5, поэтому полной совместимости нет как в одну, так и в другую сторону. Такие роли и программами экранного доступа обрабатываются несколько иначе, поэтому с ними вообще лучше не связываться, если в проекте нет серьёзных специалистов по accessibility, понимающих все подводные камни.

Кроме того, проблему использования нескольких одинаковых семантических областей HTML5 можно решать и другим способом, а именно добавлением к ним поясняющих меток. Например, если в интерфейсе несколько навигационных панелей, то имеет смысл указать их назначение, чтобы пользователь программы экранного доступа сразу понимал разницу.

Листинг 4:

		<header role="banner">
			Верхний колонтитул
		</header>
		<aside role="complementary" aria-label="Боковое меню">
			<nav role="navigation" aria-label="Тематические категории">
				Основная навигационная панель
			</nav>
			<nav role="navigation" aria-label="Разделы">
				Контекстнозависимая навигационная панель
			</nav>
		</aside>
		<aside role="complementary" aria-label="Реклама">
			Рекламный блок
		</aside>
		<main role="main">
			Основное содержимое
			<aside role="complementary" aria-label="Теги">
				Теги основного содержимого
			</aside>
		</main>
		<footer role="contentinfo">
			Нижний колонтитул
		</footer>


То есть атрибут aria-label позволяет задать дополнительную текстовую метку, которая будет пояснять назначение данного блока. Причём важно понимать, что aria-label именно дополняет role, поэтому не надо в её тексте дублировать информацию о семантическом назначении блока, например, совсем не нужно для nav писать, что это «Область навигации по разделам», достаточно просто написать «Разделы». Ну а для тега main вообще нет необходимости прописывать aria-label, так как он в принципе должен быть на странице лишь в единственном экземпляре и его назначение итак понятно. А вот для aside, footer, header или nav поясняющую метку следует добавлять по обстоятельствам. Как правило, это имеет смысл, если на странице несколько таких элементов одного типа, что с теми же footer или header бывает не так часто.

Соблюдение несложных приёмов вёрстки, описанных в этой статье, позволит вам создавать не просто доступные, но одинаково доступные под всеми основными конфигурациями интерфейсы. И главное, всё это абсолютно никак не поломает визуальную вёрстку, потому что атрибуты role и aria-label оказывают влияние лишь на то, как страница представляется программами экранного доступа через речевой или тактильный вывод информации.

Напоследок две ссылки, по которым можно более подробно ознакомиться с семантическими возможностями HTML5 и WAI-ARIA:

  • +13
  • 30,1k
  • 9
Поделиться публикацией

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

    0
    Не очень хорошо знаком с ситуацией, подскажите, WAI-ARIA как-то согласуется с ГОСТ о accessibility?
      +5
      WAI-ARIA — это чисто технический стандарт, где описана конкретная технология: какие есть атрибуты, их значения, и когда и как всё это применять. ГОСТ же скорей относится к менеджерским документам, он декларирует, что интерфейс должен быть доступен в таких-то и таких-то условиях, но как именно этого достичь с технической точки зрения там, по большому счёту, не написано.

      Вообще у ГОСТа Р52872-2007 есть две версии: старая, которая вообще мало с чем согласуется, и новая, у которой тоже куча проблем, но она в значительной степени построена на повторении идей стандарта WCAG 2.0 от W3C. WCAG 2.0 в общем-то тоже скорей менеджерский документ, но более комплексный и всеобъемлющий, плюс с более внятной методологией оценки соответствия, поэтому я бы советовал читать его, а не ГОСТ.

      Если что, у WCAG 2.0 есть и уполномоченный русский перевод. Кстати, Р52872-2007 ссылается не на этот перевод WCAG, потому что его тогда ещё не было, так что к корректности самого этого ГОСТа в принципе есть вопросы, даже не говоря о том, что он покрывает лишь один аспект доступности, а WCAG всеобъемлющ.
      +2
      Ну а для тегов header, main или footer вообще нет необходимости прописывать aria-label, так как они в принципе должны быть на странице лишь в единственном экземпляре и их назначение итак понятно.

      Не совсем верно: header и footer могут быть вложены в section, article или ещё куда угодно, поэтому далеко не всегда будут в единственном экземпляре. А main должен быть уникален, да.
        0
        Да, вы правы. Подкорректировал текст статьи. Спасибо.
          0
          Вопрос, а почему main должен быть один? Например у меня бывают всплывающие модальные окна с role=«ariadialog», на рамках которых фокус удерживается принудительно. Там тоже могут быть теги main как понимаю.

          Может правило не столь категоричное?
          • НЛО прилетело и опубликовало эту надпись здесь
        • НЛО прилетело и опубликовало эту надпись здесь
            0
            Вторая ссылка (в конце статьи) протухла.

            Чтобы два раза не вставать: не посоветуете ли каких-то гайдов по обеспечению accessability – хотя бы для экранных читалок. Как-то в статьях редко разбирают, что именно будет прочитано для той или иной разметки; или там чего установить, чтобы потестировать
              0
              > Вторая ссылка (в конце статьи) протухла.


              Ссылку починил, но она там идёт на раздел большой спецификации, так что возможно не сразу очевидно. Нужен раздел «5. The Roles Model». Он тоже не маленький, так что можно по оглавлению посмотреть интересующий подраздел, если возник какой-то точечный вопрос. Конкретно роли семантических областей страницы, про которые и был этот пост, называются Landmark Roles (это раздел 5.3.4 спецификации).

              > Чтобы два раза не вставать: не посоветуете ли каких-то гайдов по обеспечению accessability – хотя бы для экранных читалок.


              Есть несколько источников, с которыми имеет смысл работать:
              1. Web Content Accessibility Guidelines (WCAG) 2.1 — базовый стандарт от W3C. Он посвящён в основном концептуальным вопросам, то есть не освещает конкретные технические решения, а даёт понимание тех проблем, которые надо учитывать. Скорей что-то типа ориентира для формулировки ТЗ. Полезно для общего понимания проблематики web-доступности во всех аспектах.
              2. Accessible Rich Internet Applications (WAI-ARIA) 1.1 — основная спецификация технологии обеспечения доступности rich internet applications от W3C. Это именно технический документ для разработчиков, описывающий то, как нужно решать задачи обеспечения web-доступности для программ чтения экрана и прочего вспомогательного ПО. Имеет смысл хотя бы раз ознакомительно пробежать весь документ, чтобы представлять набор решений и освоить его на уровне «кажется что-то про это я где-то видел», ну и потом уже прибегать к нему как к справочнику по конкретным ситуациям. Это часть целого набора спецификаций, сосредоточенная на основных проблемах, связанных с доступностью базовых элементов страницы, но в отдельных сложных случаях, типа обеспечения доступности SVG и прочего, могут понадобиться остальные документы, полный перечень которых есть на странице WAI-ARIA Overview.
              3. WAI-ARIA Authoring Practices 1.1 — документ от W3C, описывающий некоторые неочевидные аспекты применения стандарта ARIA 1.1 и содержащий конкретные шаблоны проектирования интерфейса для базовых элементов. Вместо того, чтобы изобретать велосипед и пытаться имплементировать WAI-ARIA в свои кастомные элементы интерфейса, имеет смысл поискать здесь готовую реализацию.
              4. Ну и конкретные задачи, типа обеспечения доступности выпадающего меню или чего-нибудь ещё, можно просто искать в Интернете с ключевыми словами, типа «web accessibility drop-down menu» или «accessible drop-down menu». В результатах, в первую очередь, стоит обращать внимание на отдельные материалы с примерами с сайтов W3C, браузеров и браузерных движков, а также крупных информационных ресурсов, типа MDN. Всякие статьи в личных блогах рейтингуйте ниже, потому что там не всё и не всегда правильно, а пока у вас не наработан опыт, вы можете это не заметить и повторить плохое решение.


              > Как-то в статьях редко разбирают, что именно будет прочитано для той или иной разметки; или там чего установить, чтобы потестировать


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

              В целом, тестирование web-доступности, как и везде, делится на автоматизированное и ручное.

              Из автоматизированных методов можно отметить такой инструмент как Axe, который можно встроить в систему непрерывной интеграции, а также внутренние инструменты в браузерах, а именно: аудит доступности в Chrome и Инспектор доступности в Firefox.

              Для ручного тестирования надо брать программу чтения экрана, осваивать принципы невизуальной работы в web, ну и проверять, насколько с сайтом вообще можно работать, получая информацию только от screenreader'а и пользуясь его способами взаимодействия со страницей. Обо всех нюансах, типа иной статистики распространённости браузеров и операционных систем, а также статистике распространённости самих программ чтения экрана на разных языковых рынках говорить очень долго. Это вряд ли формат комментария. Впрочем, и мало кто из обычных разработчиков готов будет настолько глубоко с этим связываться. Поэтому я опишу базовый вариант ручного тестирования.

              Лучше всего взять Windows и установить туда бесплатную программу NVDA (есть и portable вариант запуска). По команде Insert+N или через иконку в области задач можно открыть меню программы, где, помимо прочего, будет справка и настройки. На слух понимать программу со стандартным синтезатором речи, скорей всего, будет тяжело. Поэтому можно либо поставить более качественный бесплатный синтезатор речи RHVoice (версия в виде дополнения для NVDA), либо через меню «Сервис» включить функцию «Просмоторщик речи», которая отобразит на экране область, где будут выводиться текстом все фразы программы.

              Далее открываем сайт в браузере и проверяем, читается ли весь контент и элементы управления, а также осуществляется ли с ними корректное взаимодействие. Имеет смысл по CTRL+Home переместиться в начало, а потом стрелкой вниз пройтись по всей странице. Конкретно семантические области страницы можно перебрать нажатием D (сверху вниз) и Shift+D (снизу вверх). Также можно по Insert+F7 открыть диалог агрегированного отображения элементов страницы, выбрать там переключателем «Ориентиры» и в этом окне будет показано иерархическое дерево семантических областей. Подробнее обо всех командах работы в Интернете можно почитать в руководстве NVDA, доступном через меню программы.

              У многих разработчиков основной системой является macOS, где есть встроенная функция чтения экрана VoiceOver. К сожалению, VoiceOver довольно слабое решение в отношении обеспечения невизуальной доступности web-контента, да к тому же с рядом крайне спорных технологических решений, ну и в англоязычной среде имеющее распространение среди реальных пользователей меньше 10%, а в русскоязычной — меньше 5%. Это одна из проблем индустрии, потому что многие разработчики если что-то руками и проверяют, то как раз на VoiceOver, ну и порой получают не лучшее качество.

              Впрочем, для совсем базовых вещей VoiceOver тоже можно использовать. Он активируется по команде CMD+F5 (в зависимости от настроек клавиатуры может быть FN+CMD+F5). Настройки открываются по CMD+Option+F8. В настройках можно включить так называемую панель субтитров, которая также будет выводить фразы в виде текста на экране.

              С VoiceOver имеет смысл включить быструю навигацию по одновременному нажатию стрелок вправо и влево, а потом пройтись по содержимому страницы стрелкой вправо. Отдельные блоки контента он сворачивает в условные контейнеры, которые можно открыть командой Вниз+Вправо. Элемент активируется командой Вверх+Вниз. Справку по командам можно открыть по CMD+Option+H, ну и при запуске сразу будет открыто руководство для быстрого освоения, хотя раздела по обучению web-навигации там по-моему до сих пор нет. Полный учебник по VoiceOver лежит здесь.

              Это я попытался ответить на ваш вопрос кратко, так что, как видите, поднятая тема очень обширная, если краткие ответы получаются такими длинными. :-)

              Для крупных проектов, конечно, нужен отдельный QA-специалист по accessibility, который способен на высоком уровне проводить ручное тестирование с учётом всей неконсистентности браузеров, программ чтения экрана и прочего, а также вырабатывать технические рекомендации и решения для обычных разработчиков, но такая практика существует даже не в каждой большой западной компании. Это порождает замкнутый круг: когда такой специалист нужен, его трудно найти, а трудно его найти, потому что массово такие специалисты невостребованы, так что мало кто пробует развиваться в эту сторону. Впрочем, это уже совсем другая история…

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое