HTML

HTML: доступность и ARIA основы

📚 25 вопросовПройти тест →
Лекция

HTML: доступность и ARIA основы

HTML

HTML: доступность и ARIA основы

Введение: как пандус у входа ♿

Представьте вход в здание без пандуса. Часть людей просто не сможет попасть внутрь.
Веб‑страницы устроены так же: без доступности кто‑то не сможет ими пользоваться.
💡 Совет: доступность — это не «доп. опция», а базовый стандарт качества.
Вывод: доступный HTML делает сайт понятным для всех.

Проблема: сайт удобен не для всех ❌

Без доступности:
  • кнопки без подписей;
  • формы без label;
  • экранные дикторы читают «кашу».
С доступностью:
  • структура понятна;
  • фокус виден;
  • ошибки объяснены.
Вывод: доступность = понятность + равные возможности.

Чем помогает и как работает

  • делает интерфейс управляемым с клавиатуры, скринридера и разных устройств ввода;
  • снижает число UX-ошибок за счёт понятной структуры и подписей;
  • улучшает качество продукта: доступный интерфейс проще поддерживать и масштабировать.
Как это работает:
  1. Сначала строим правильную семантику страницы (header, nav, main, заголовки, формы).
  2. Проверяем, что интерактив доступен с клавиатуры и имеет понятный текст/роль.
  3. Добавляем ARIA только там, где нативной семантики недостаточно.
  4. Тестируем сценарии с фокусом, скринридером и динамическими сообщениями.
Вывод: доступность работает как системный слой качества, а не как набор разрозненных атрибутов.

Что такое доступность (Accessibility)

Доступность — это способность сайта быть понятным и управляемым для всех пользователей:
включая людей с нарушением зрения, моторики и когнитивных особенностей.
Вывод: доступность — это часть UX и качество продукта.

Ключевые термины (простыми словами)

  • Accessibility (доступность) — когда интерфейс удобен всем.
  • ARIA (Accessible Rich Internet Applications) — набор атрибутов для доступности.
  • Landmark (ориентир) — смысловые зоны страницы: header, nav, main.
  • Focus (фокус) — элемент, с которым работает клавиатура.
  • Screen reader (скринридер) — программа, читающая страницу вслух.
  • aria-label — краткая подпись для элемента.
  • aria-labelledby — ссылка на существующий текст.
  • aria-describedby — текст подсказки/ошибки.
  • aria-live — озвучивание изменений.
  • tabindex — порядок фокуса.
Вывод: это словарь, который помогает делать интерфейсы доступными.

1. Семантика — основа доступности

Назначение: дать каждому блоку страницы понятную роль.
Простыми словами: семантика объясняет браузеру и скринридеру, где меню, где основная часть, а где подвал.
Аналогия: указатели в помещении, по которым человек быстро ориентируется.
Пример:
<header>...</header><nav>...</nav><main>...</main><footer>...</footer>
🔎 Как это происходит на практике:
  1. Размечаю каркас страницы семантическими тегами.
  2. Проверяю, что в main находится уникальный основной контент.
  3. Сравниваю навигацию скринридера до и после семантической разметки.
Характеристики:
  • ✅ Даёт ориентиры для assistive-технологий.
  • ✅ Улучшает читабельность DOM-структуры.
  • ✅ Снижает зависимость от ARIA-патчей.
❗ Когда использовать: при создании любой страницы, где есть структура контента.
Вывод: семантика — это первый и самый важный слой доступности.

2. Заголовки — структура чтения

Назначение: построить иерархию контента для чтения и навигации.
Простыми словами: заголовки показывают, что главное, а что подчинённое.
Пример:
<h1>Курс по HTML</h1><h2>Программа</h2><h3>Блок 1</h3>
🔎 Как это происходит на практике:
  1. Определяю один h1 на страницу.
  2. Выстраиваю разделы через h2, подпункты через h3.
  3. Проверяю отсутствие скачков уровней (h2h4 без h3).
Характеристики:
  • ✅ Формирует логическую карту страницы.
  • ✅ Улучшает навигацию скринридера по заголовкам.
  • ✅ Упрощает восприятие больших текстов.
❗ Когда использовать: в каждом разделе, где нужно явно разделить смысловые блоки.
Вывод: иерархия заголовков делает контент предсказуемым для всех пользователей.

3. Ссылки и кнопки

Назначение: разделить навигационные переходы и действия интерфейса.
Простыми словами: ссылка ведёт на другую страницу/якорь, кнопка выполняет действие на текущей.
Пример:
<a href="/courses">Перейти к курсам</a><button type="button">Открыть фильтры</button>
🔎 Как это происходит на практике:
  1. Проверяю цель элемента: переход или действие.
  2. Пишу текст, который понятен вне контекста («Подробнее о тарифах»).
  3. Тестирую управление элементами с клавиатуры.
Характеристики:
  • ✅ Семантически корректные элементы дают корректные роли.
  • ✅ Понятный текст ссылки улучшает доступность и SEO.
  • ✅ Уменьшает путаницу для пользователей скринридеров.
❗ Когда использовать: ссылки — для переходов, кнопки — для локальных действий и изменения состояния.
Вывод: правильный выбор тега напрямую влияет на понятность интерфейса.

4. Формы: label, fieldset, legend

Назначение: сделать ввод данных понятным и доступным.
Простыми словами: label объясняет поле, а fieldset + legend объединяют связанные группы.
Пример:
<fieldset>  <legend>Контактные данные</legend>  <label for="email">Email</label>  <input id="email" name="email" /></fieldset>
🔎 Как это происходит на практике:
  1. Связываю label for и id каждого поля.
  2. Группирую логически связанные поля в fieldset.
  3. Добавляю legend, чтобы обозначить смысл группы.
Характеристики:
  • ✅ Улучшает понимание формы для всех каналов восприятия.
  • ✅ Клик по label помогает быстрому вводу.
  • ✅ Группы полей читаются как единые блоки.
❗ Когда использовать: в любой форме, где есть ввод данных и группы связанных полей.
Вывод: доступная форма начинается с корректных подписей и группировки.

5. alt у изображений

Назначение: передать смысл изображения, когда его нельзя увидеть.
Простыми словами: alt — это текстовое объяснение картинки для скринридера и fallback-сценариев.
Пример:
<img src="/cover.jpg" alt="Обложка курса по HTML" />
🔎 Как это происходит на практике:
  1. Определяю, несёт ли изображение смысл.
  2. Для смысловых изображений пишу короткий и точный alt.
  3. Для декоративных изображений использую пустой alt="".
Характеристики:
  • ✅ Улучшает доступность контентных изображений.
  • ✅ Помогает понять смысл при недоступной картинке.
  • ✅ Должен быть информативным, но без лишних слов.
❗ Когда использовать: для каждого img: смысловой alt или пустой alt для декора.
Вывод: правильный alt делает визуальный контент доступным без потери смысла.

6. ARIA: когда и зачем

Назначение: дополнять доступность там, где нативного HTML недостаточно.
Простыми словами: ARIA — это точечная настройка, а не замена нормальной семантики.
Пример:
<button aria-label="Открыть поиск">🔍</button>
🔎 Как это происходит на практике:
  1. Сначала проверяю, можно ли решить задачу нативным HTML.
  2. Добавляю ARIA только при реальной необходимости.
  3. Проверяю, что ARIA не конфликтует с нативной ролью элемента.
Характеристики:
  • ✅ Расширяет доступность сложных UI-компонентов.
  • ✅ Требует точности: неверная ARIA может ухудшить UX.
  • ✅ Лучше всего работает вместе с корректной семантикой.
❗ Когда использовать: когда нативный HTML не даёт достаточной информации assistive-технологиям.
Вывод: ARIA полезна как инструмент усиления, но не как костыль вместо семантики.

7. aria-label, aria-labelledby, aria-describedby

Назначение: управлять именем и описанием элемента для ассистивных технологий.
Простыми словами: aria-label задаёт имя вручную, aria-labelledby берёт его из видимого текста, aria-describedby добавляет пояснение.
Пример:
<h2 id="course-title">Курс по HTML</h2><button aria-labelledby="course-title" aria-describedby="course-hint">Подробнее</button><p id="course-hint">Откроется описание программы</p>
🔎 Как это происходит на практике:
  1. Проверяю, есть ли у элемента видимый текст для имени.
  2. Если есть — предпочитаю aria-labelledby.
  3. Для дополнительного контекста подключаю aria-describedby.
Характеристики:
  • ✅ Помогает формировать понятное доступное имя элемента.
  • ✅ Снижает дублирование текста при aria-labelledby.
  • ✅ Улучшает понимание сложных кнопок и полей.
❗ Когда использовать: aria-label — для иконок без текста; aria-labelledby — если есть готовый заголовок; aria-describedby — для подсказки/ошибки.
Вывод: лучше опираться на видимый текст и добавлять ARIA-пояснения только по задаче.

8. aria-live — динамические сообщения

Назначение: озвучивать изменения интерфейса, которые происходят без перезагрузки страницы.
Простыми словами: если ошибка или статус появились динамически, скринридер должен услышать это автоматически.
Пример:
<p id="form-errors" role="status" aria-live="polite"></p>
🔎 Как это происходит на практике:
  1. Добавляю live-регион рядом с зоной сообщений.
  2. При ошибке/успехе записываю туда актуальный текст.
  3. Проверяю озвучивание в NVDA/VoiceOver.
Характеристики:
  • ✅ Работает для динамического контента.
  • polite — мягкое уведомление, assertive — приоритетное.
  • ✅ Улучшает доступность форм и SPA-интерфейсов.
❗ Когда использовать: для ошибок, статусов загрузки, подтверждений и других динамических уведомлений.
Вывод: aria-live закрывает критичный пробел в доступности динамического UI.

9. aria-hidden — скрытие от скринридеров

Назначение: убрать из озвучивания декоративные и дублирующие элементы.
Простыми словами: если элемент не несёт смысла, его можно скрыть от скринридера.
Пример:
<span aria-hidden="true">★</span>
🔎 Как это происходит на практике:
  1. Отделяю декоративные элементы от смысловых.
  2. Для декора ставлю aria-hidden="true".
  3. Проверяю, что интерактивные элементы остаются озвучиваемыми.
Характеристики:
  • ✅ Уменьшает шум при озвучивании интерфейса.
  • ✅ Подходит для декоративных иконок/символов.
  • ✅ Опасен при неверном применении к интерактиву.
❗ Когда использовать: только для декоративных элементов, которые не несут действия и смысла.
Вывод: aria-hidden полезен для чистоты озвучивания, но требует строгой дисциплины.

10. tabindex и порядок фокуса

Назначение: контролировать навигацию с клавиатуры без ломки естественного порядка.
Простыми словами: фокус должен идти логично по интерфейсу так же, как читает пользователь глазами.
Пример:
<div tabindex="0">Карточка курса</div><div tabindex="-1" id="modal-title">Заголовок модалки</div>
🔎 Как это происходит на практике:
  1. Тестирую интерфейс табом от начала до конца.
  2. Для кастомного интерактива ставлю tabindex="0".
  3. Для программного фокуса в модалках использую -1.
Характеристики:
  • 0 включает элемент в естественный порядок.
  • -1 даёт программный фокус без таб-навигации.
  • ✅ Положительные значения часто ломают UX.
❗ Когда использовать: 0 для кастомных интерактивных элементов, -1 для управляемого фокуса; избегать 1+.
Вывод: логичный порядок фокуса — базовый критерий доступного интерфейса.

11. Skip‑link (ссылка «пропустить к контенту»)

Назначение: позволить быстро перейти к основному контенту, минуя повторяющееся меню.
Простыми словами: пользователь клавиатуры не должен проходить десятки табов на каждом экране.
Пример:
<a href="#main" class="skip-link">Перейти к контенту</a><main id="main">...</main>
🔎 Как это происходит на практике:
  1. Добавляю skip-link первым интерактивным элементом страницы.
  2. Делаю ссылку видимой при фокусе.
  3. Проверяю, что переход реально переводит к main.
Характеристики:
  • ✅ Экономит время при клавиатурной навигации.
  • ✅ Особенно важен на страницах с длинной шапкой/фильтрами.
  • ✅ Прост в реализации и даёт быстрый UX-эффект.
❗ Когда использовать: на всех страницах с повторяемой навигацией перед основным контентом.
Вывод: skip-link резко повышает удобство интерфейса для клавиатурных пользователей.

Сравнение: aria-label vs aria-labelledby vs aria-describedby

АтрибутЧто делаетКогда использовать
aria-labelЗадаёт короткую подпись вручнуюНет видимого текста
aria-labelledbyСсылается на существующий текстЕсть видимый заголовок
aria-describedbyДобавляет пояснение/ошибкуНужна подсказка

Часто спрашивают на собеседованиях

  • Почему label важен? Он связывает поле и смысл.
  • Что такое ARIA и зачем она? Для доступности, когда семантики недостаточно.
  • Когда использовать aria-label? Когда нет видимого текста.
  • Зачем aria-live? Чтобы динамические ошибки были озвучены.
  • Почему нельзя tabindex="1"? Ломает естественный порядок.
Вывод: это базовые вопросы по HTML‑доступности.

Типичные ошибки

Ошибка 1: Кнопка‑иконка без подписи

❌ Неправильно: скринридер читает «button».
✅ Правильно: aria-label.

Ошибка 2: Placeholder вместо label

❌ Неправильно: текст исчезает при вводе.
✅ Правильно: отдельный label.

Ошибка 3: Ссылки «кликни тут»

❌ Неправильно: непонятно, куда ведёт.
✅ Правильно: ясный текст.

Ошибка 4: aria-hidden на интерактивных элементах

❌ Неправильно: кнопка становится невидимой для скринридера.
✅ Правильно: скрывать только декор.

Ошибка 5: tabindex="2" и выше

❌ Неправильно: порядок ломается.
✅ Правильно: 0 или -1.

Ошибка 6: Нет skip‑link

❌ Неправильно: длинный путь табами.
✅ Правильно: ссылка «к контенту».

Best Practices

  • Используйте семантические теги.
  • Всегда пишите понятный текст ссылок.
  • Добавляйте label к полям.
  • Пишите alt для изображений.
  • Используйте ARIA только по необходимости.
  • Следите за порядком фокуса.
  • Добавляйте aria-live для ошибок.

Заключение

Ключевые мысли

🎯 Доступность — часть качества интерфейса.
🎯 Семантика и ARIA делают контент понятным.
🎯 Порядок фокуса и подписи — базовые вещи.
Сделайте страницу доступной — и она станет удобной для всех.
🎯

Проверьте знания

Закрепите материал — пройдите тест по теме «HTML: доступность и ARIA основы»

Пройти тест →