Основы доступного HTML

Базовые рекомендации по доступной разметке: важность семантических тегов и их контента, хорошие практики, использование WAI-ARIA и отладка доступности.

Время чтения: 10 мин

Кратко

Скопировано

Веб-доступность кроет в себе множество нюансов. Однако есть основные правила, которые помогут написать более доступный HTML-код. В них входит:

  • правильное использование семантических тегов;
  • очевидное и доступное содержимое тегов — контент сайта;
  • использование подписей для элементов форм — тег <label>;
  • масштабируемость, которая настраивается с помощью user-scalable и maximum-scale в теге <meta>;
  • дополнительное использование ARIA, когда не помогают только нативные HTML-элементы.

Семантика и вспомогательные технологии

Скопировано

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

Семантические HTML-теги помогают пользователям определить, как взаимодействовать с элементами и быстро ориентироваться по содержимому сайта. Например, скринридер понимает, что тег <button> кликабельный и сообщает, что его можно активировать при нажатии клавиш Enter и Space. Также на элемент <button> можно сделать фокус клавишей Tab. Доступность уже встроена в нативный тег. Если использовать для кнопки <div> или <span>, то нужно указать tabindex="0" — атрибут, который делает элемент фокусируемым. Однако этого недостаточно. Нужно ещё добавить тегу нужную роль, поддержать нажатие на пробел и Enter и проработать стили для состояния фокуса.

Есть и другие причины, почему семантика так важна. Чтобы быстро передвигаться по элементам сайта — заголовкам, формам, таблицам и спискам, — пользователи скринридеров используют горячие клавиши. Например, чтобы перемещаться по заголовкам есть клавиши H и Shift. Сочетания клавиш могут варьироваться в зависимости от скринридера, но во всех есть навигация по определённым семантическим элементам.

Почему семантическая вёрстка лучше ARIA

Скопировано

Существует заблуждение, что использование ARIA-атрибутов является неотъемлемой частью доступного HTML. Однако ARIA — это всего лишь вспомогательный инструмент, который полезен в случаях, где не хватает функциональности нативных HTML-тегов. Например, в HTML нет тегов для вкладок, но есть ARIA-роли tab, tablist и tabpanel.

В большинстве случаев семантическая вёрстка лучше ARIA, так как она автоматически предоставляет доступные роли и состояния элементов. Если не знаете, как правильно пользоваться ARIA, такая разметка запутает пользователей. К примеру, если <a> задать роль menuitem, то он перестанет быть ссылкой и станет пунктом меню.

        
          
          <a role="menuitem">Для скринридера я элемент меню, а не ссылка</a>
          <a role="menuitem">Для скринридера я элемент меню, а не ссылка</a>

        
        
          
        
      

К тому же, поддержка ARIA в разных скринридерах отличается. Например, <audio> в сочетание с aria-label не поддерживается ни одним из известных скринридеров.

Если нативный HTML-тег не помогает решить задачу, следуйте стандартам и хорошим практикам, когда разрабатываете кастомный элемент. Например, можно заглянуть в ARIA Authoring Practices Guide или использовать готовые компоненты вроде доступного диалога.

Не все семантические теги доступны

Скопировано

Не все нативные теги доступны по умолчанию. Например, <details> и <summary> ведут себя по-разному в зависимости от комбинации браузера и скринридера. Теги позволяют искать текст, спрятанный внутри <details>, и при поиске автоматически показывают блок с информацией. В теории при клике, нажатии или тапе на <details> должно раскрываться его детальное содержимое. Однако при взаимодействии с этим элементом TalkBack в Firefox и мобильный VoiceOver в Safari не объявляют его роль и состояние правильно. Так что, пока нет полной поддержки этих тегов.

Даже такие основные элементы как <label> и <input> могут быть неполностью доступны скринридеру. Существует проблема с вложенным в <label> контентом в Safari. В случае, если контент подписи вложен в <label> как на следующем примере:

        
          
          <label for="name">  <span>Имя</span>  <span>Введи своё полное имя</span>  <input type="text" id="name"></label>
          <label for="name">
  <span>Имя</span>
  <span>Введи своё полное имя</span>
  <input type="text" id="name">
</label>

        
        
          
        
      

VoiceOver в Safari не прочитает «Введи своё полное имя».

Лучше всегда тестировать код, даже если используете только возможности HTML. Ещё можете посмотреть как скринридеры ведут себя с разными тегами в HTML test cases.

Роли, состояния и свойства

Скопировано

ARIA позволяет задавать роли, состояния и свойства HTML-элементам. Это то, что уже есть у многих семантических тегов по умолчанию.

Роли определяют значение элемента в интерфейсе. Они есть у многих нативных HTML-тегов. Роль navigation есть y тега <nav>, complementary у <aside>.

У <div> и <span> на самом деле тоже есть роли. Это нейтральная generic, которая означает безымянный контейнер. Скринридеры не объявляют эту роль, но могут зачитывать текст из тегов. Так как <div> и <span> нейтральные теги, их роли можно перезаписывать с помощью role. Только имейте в виду, что атрибут перепишет любую нативную роль тега. Например, скринридер не объявит <ul role="tabpanel"> как список.

Свойства и состояния указываются атрибутами aria-* и придают дополнительное значение элементам. Например, с помощью aria-describedby можно добавить дополнительное видимое описание, а благодаря aria-required="true" указать какое поле в форме обязательное.

Роли и атрибуты могут также создавать связи между элементами. Например, при разработке вкладок нужно правильно использовать комбинацию из ролей tablist, tab, tabpanel и атрибутов aria-controls и aria-selected. Неправильно указанные связи запутают пользователей.

Текстовое содержимое HTML-тегов

Скопировано

Текстовое содержимое HTML-тегов не менее важно, чем их правильное использование. Рассмотрим пример со ссылкой.

        
          
          Узнать подробнее об утконосе можно <a href="https://ru.wikipedia.org/wiki/Утконос">здесь</a>
          Узнать подробнее об утконосе можно <a href="https://ru.wikipedia.org/wiki/Утконос">здесь</a>

        
        
          
        
      

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

Более доступный вариант предыдущего примера.

        
          
          <a href="https://ru.wikipedia.org/wiki/Утконос">Подробнее об утконосе</a>
          <a href="https://ru.wikipedia.org/wiki/Утконос">Подробнее об утконосе</a>

        
        
          
        
      

В доступности ещё есть понятие имени, которое выполняет две важные функции:

  1. Кратко описывает значение элемента (в 1–3 словах).
  2. Служит отличительной чертой среди других элементов.

У многих элементов, например, ссылок, кнопок, заголовков и так далее имя формируется из их текстового содержимого. Есть и другие способы добавить имя. Атрибут <label> задаёт имя элементам форм, а <legend> — их группе. Тег <caption> используют для таблиц. <figcaption> — для иллюстраций внутри тега <figure>. Также можно использовать ARIA-атрибуты aria-label и aria-labelledby. Важно помнить, что ARIA перепишет имена тегов, которые получают его из их текстового содержимого. Это может повлиять на доступность и читаемость кода.

Для одних тегов тот или иной способ придать доступное имя работает лучше, чем для других. На сайте ARIA Authoring Practices Guide собраны рекомендации по доступным именам в зависимости от роли HTML-тега.

Для доступности важны не только имена, но и остальной текст на сайте. Например, аббревиатуры могут сделать содержимое менее доступным. Есть <abbr> для аббревиатур, но он недоступен для пользователей клавиатуры и сенсорных устройств. Поэтому советуют использовать термины без сокращений или раскрывать значение аббревиатур в скобках при первом упоминании.

Хорошие практики

Скопировано

Основные настройки сайта

Скопировано

Доступный сайт начинается с настроек в <head>. Сайт делают более доступным правильно указанный язык в атрибуте lang у <html>, атрибуты масштабируемости user-scalable и maximum-scale в <meta>, а также уникальный для каждой страницы заголовок <title>.

По результатам исследований «Веб-альманаха» у 28% мобильных версий страниц есть проблемы с масштабируемостью. Это связано с тем, что у атрибута user-scalable указаны значения no или 0, а maximum-scale меньше 2. Из-за этого пользователи не могут увеличить текст с помощью возможностей браузера и сайты не соответствует критерию доступности об увеличении текста до как минимум 200%.

Кнопки-иконки

Скопировано

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

Некоторые символы в иконках могут по-разному интерпретироваться. Например, в Швеции и Финляндии значок «галочка» используют в случае неправильного ответа, что противоположно его значению в англоговорящей среде. Поэтому использование иконок может запутать не только пользователей скринридеров, но других людей.

Подписи

Скопировано

В 2022 году на 63% сайтов использовали атрибут placeholder вместо подписи <label>. Несмотря на то что, визуально placeholder может дать подсказку как заполнить поле, он не является доступным для всех пользователей по многим причинам. Например, он исчезает при фокусе на элемент и часто недостаточно контрастный.

Также подписи могут иметь и другие элементы, например, картинки <img>. Атрибут alt для описания содержания картинки — важный критерий доступности страницы. Он должен быть у всех <img>, но не всегда описывать картинку. Декоративные элементы не нуждаются в описании и могут иметь пустое значение — alt="".

Порядок заголовков

Скопировано

Другая популярная ошибка — неправильный порядок заголовков, для которых используют от <h1> до <h6>. Часто уровень заголовка выбирают на основе его стиля, а не на логическом порядке. В результате, на 42% сайтов неправильная иерархия заголовков. Для доступности важно, чтобы на странице был один <h1>, а все остальные заголовки располагались в последовательном порядке. Это облегчает навигацию по сайту для пользователей и позволяет передвигаться от заголовка к заголовку с помощью горячих клавиш для скринридеров.

Правильную иерархию заголовков подробнее описывает правило «Порядок заголовков» на сайте Deque University.

Отладка доступности в HTML

Скопировано

Существуют разные инструменты для отладки и тестирования доступности.

В браузерных инструментах для веб-разработки обязательно найдётся инспектор доступности. Например, панель доступности в Chrome и инспектор доступности в Firefox. В них можно посмотреть на дерево доступности (accessibility tree). В него попадают роли, свойства и состояния HTML-элементов.

Тестировать доступность можно также с помощью Lighthouse или расширения axe. Ещё один хороший инструмент с точки зрения доступности разметки — это валидатор для HTML. На сайте W3C представлен полный представлен полный список разных инструментов для тестирования и отладки доступности.

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