Back

Понимание ролей доступности в HTML

Понимание ролей доступности в HTML

Роли доступности сообщают вспомогательным технологиям, чем является элемент, а не как он выглядит. Когда программа чтения с экрана встречает кнопку, ей нужно знать, что это кнопка — будь то нативный элемент <button> или пользовательский компонент с role="button". Ошибка в этом означает, что миллионы пользователей не смогут эффективно перемещаться по вашему интерфейсу.

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

Ключевые выводы

  • Роли доступности определяют, чем является элемент для вспомогательных технологий, а не его визуальное представление
  • Дерево доступности содержит имя, роль и значение/состояние для каждого элемента
  • Семантический HTML предоставляет неявные роли — используйте ARIA только когда HTML недостаточно
  • Тестирование с реальными вспомогательными технологиями гарантирует, что ваша реализация работает для реальных пользователей

Как роли работают в дереве доступности

У каждой веб-страницы есть два дерева: знакомое вам дерево DOM и дерево доступности, которое фактически читают вспомогательные технологии. Дерево доступности следует простой модели: каждый элемент имеет имя, роль и значение/состояние.

<!-- DOM-элемент -->
<button aria-pressed="true">Mute</button>

<!-- Представление в дереве доступности -->
Name: "Mute"
Role: button
Value/State: pressed=true

Браузер автоматически строит это дерево доступности из вашего HTML, сопоставляя семантические элементы с их неявными ролями. Элемент <nav> становится навигационным ориентиром, <button> становится виджетом кнопки. ARIA-роли позволяют вам изменять это дерево, когда нативного HTML недостаточно — но они должны быть вашим последним средством, а не первым выбором.

Четыре основные категории ролей

Роли-ориентиры (Landmark Roles)

Роли-ориентиры определяют регионы страницы для навигации. Современный HTML5 предоставляет большинство из них нативно:

  • <header> → роль banner (когда не внутри <article> или <section>)
  • <nav> → роль navigation
  • <main> → роль main
  • <aside> → роль complementary
  • <footer> → роль contentinfo (когда не внутри <article> или <section>)

Лучшая практика: Используйте семантические HTML-элементы вместо <div role="navigation">. Избыточность <nav role="navigation"> не добавляет ценности — элемент уже имеет эту роль неявно.

Роли виджетов (Widget Roles)

Роли виджетов описывают интерактивные элементы управления. Они критически важны для пользовательских компонентов, которые не могут использовать нативные элементы:

<!-- Хорошо: Пользовательский интерфейс вкладок -->
<div role="tablist">
  <button role="tab" aria-selected="true">Settings</button>
  <button role="tab" aria-selected="false">Profile</button>
</div>

<!-- Плохо: Ненужная ARIA -->
<button role="button">Click me</button> <!-- Избыточно -->

Роли структуры документа (Document Structure Roles)

Эти роли описывают организацию контента: заголовки, списки, статьи и разделители. Опять же, предпочитайте семантический HTML:

<!-- Предпочтительно -->
<article>
  <h2>Article Title</h2>
</article>

<!-- Вместо этого -->
<div role="article">
  <div role="heading" aria-level="2">Article Title</div>
</div>

Абстрактные роли (Abstract Roles)

Абстрактные роли, такие как command или composite, являются базовыми шаблонами в WAI-ARIA. Никогда не используйте их напрямую — они существуют только для того, чтобы спецификация могла определять другие роли.

Современные лучшие практики для ARIA-ролей

Сначала предпочитайте семантический HTML

Первое правило ARIA — не используйте ARIA. Нативные HTML-элементы поставляются со встроенной поддержкой клавиатуры, управлением фокусом и семантикой доступности:

<!-- Всегда предпочитайте это -->
<button onclick="submit()">Submit</button>

<!-- Вместо этого антипаттерна -->
<div role="button" tabindex="0" onclick="submit()">Submit</div>

Версия с <div> требует дополнительного JavaScript для поддержки клавиатуры, стилизации фокуса и правильной активации — работу, которую нативная кнопка выполняет автоматически.

Избегайте избыточных ролей-ориентиров

С появлением HTML5 добавление явных ролей к семантическим элементам не требуется и может вызвать путаницу:

<!-- Не делайте так -->
<main role="main">
<nav role="navigation">
<header role="banner">

<!-- Эти элементы уже имеют неявные роли -->
<main>
<nav>
<header>

Никогда не переопределяйте нативные интерактивные роли

Изменение роли кнопки нарушает её ожидаемое поведение:

<!-- Никогда не делайте так -->
<button role="heading">Section Title</button>

<!-- Это нарушает взаимодействие с клавиатурой и ожидания программ чтения с экрана -->

Когда пользовательские роли имеют смысл

Пользовательским компонентам иногда действительно нужны ARIA-роли. Вот допустимые случаи использования:

Паттерн пользовательского диалога

<div role="dialog" aria-labelledby="dialog-title" aria-modal="true">
  <h2 id="dialog-title">Confirm Action</h2>
  <button>Cancel</button>
  <button>Confirm</button>
</div>

Пользовательский интерфейс вкладок

<div role="tablist" aria-label="User settings">
  <button role="tab" aria-selected="true" aria-controls="panel-1">General</button>
  <button role="tab" aria-selected="false" aria-controls="panel-2">Privacy</button>
</div>
<div role="tabpanel" id="panel-1">General settings content</div>

Работа с описаниями и метками

Для доступных имён и описаний следуйте этой иерархии:

  1. Видимый текст (лучше всего для всех пользователей)
  2. aria-labelledby (ссылается на видимый текст в другом месте)
  3. aria-describedby (добавляет дополнительную информацию)
  4. aria-label (когда видимый текст невозможен)
<button aria-describedby="help-text">Delete</button>
<span id="help-text">This action cannot be undone</span>

Примечание: aria-description появляется в WAI-ARIA 1.3, но имеет ограниченную поддержку. Придерживайтесь aria-describedby для продакшн-кода.

Распространённые антипаттерны, которых следует избегать

Кнопки на основе div: Создание <div role="button">, когда <button> работает отлично
Избыток ролей: Добавление ролей к каждому элементу “на всякий случай”
Конфликтующая семантика: <h2 role="button"> смешивает структуру и взаимодействие
Избыточные роли: <nav role="navigation"> не добавляет ценности

Тестирование вашей реализации

Всегда проверяйте роли с реальными вспомогательными технологиями. Инструменты разработчика браузеров теперь включают инспекторы дерева доступности — используйте их, чтобы увидеть точно то, что воспринимают программы чтения с экрана. Тестируйте с NVDA на Windows или VoiceOver на macOS, чтобы убедиться, что ваши роли превращаются в удобный опыт использования.

Заключение

Роли доступности существуют для описания того, чем что-то является, а не как оно выглядит. Нативный семантический HTML предоставляет большинство ролей неявно — используйте его в первую очередь. Резервируйте ARIA-роли для действительно пользовательских компонентов, где HTML недостаточно. Когда вы используете ARIA, убедитесь, что она соответствует рекомендациям WCAG, и тестируйте с реальными вспомогательными технологиями. Помните: отсутствие ARIA лучше, чем плохая ARIA.

Часто задаваемые вопросы

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

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

ARIA всегда побеждает нативную семантику HTML, что может нарушить ожидаемое поведение. Например, добавление role='heading' к кнопке удаляет всю функциональность кнопки для программ чтения с экрана. Вот почему вы никогда не должны переопределять роли нативных интерактивных элементов.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay