Как известно, 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. В итоге, получим следующие результаты:
Теги | 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 | Роль WAI-ARIA |
---|---|
footer | contentinfo |
header | banner |
main | main |
nav | navigation |
Кстати, что касается роли banner, специально оговоримся, что она предназначена для оборачивания именно всей шапки страницы, а не рекламного баннера. То есть она, действительно, прямой аналог тега header. Как показывает практика, некоторых слово «banner» вводит в заблуждение, и они начинают это значение присваивать именно рекламным баннерам, но это неправилльно.
Вышеприведённые соответствия позволят корректно разметить в WAI-ARIA базовые семантические области HTML5. Однако заметно, что там упомянуты далеко не все из них. Дело в том, что во-первых, некоторые семантические структуры HTML5 не имеют прямых аналогов WAI-ARIA, например, это касается тегов article или section, а во-вторых, с некоторыми из них всё не так просто, главным образом, речь, конечно, об 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">
<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 писать, что это «Область навигации по разделам», достаточно просто написать «Разделы». Ну а для тегов header, main или footer вообще нет необходимости прописывать aria-label, так как они в принципе должны быть на странице лишь в единственном экземпляре и их назначение итак понятно. А вот для aside или nav поясняющую метку следует добавлять по обстоятельствам. Как правило, это имеет смысл, если на странице несколько таких элементов одного типа.
Соблюдение несложных приёмов вёрстки, описанных в этой статье, позволит вам создавать не просто доступные, но одинаково доступные под всеми основными конфигурациями интерфейсы. И главное, всё это абсолютно никак не поломает визуальную вёрстку, потому что атрибуты role и aria-label оказывают влияние лишь на то, как страница представляется программами экранного доступа через речевой или тактильный вывод информации.
Напоследок две ссылки, по которым можно более подробно ознакомиться с семантическими возможностями HTML5 и WAI-ARIA:
Автор: Tseikovets