Урок 33

День 33 | Доступность (Accessibility)

50 мин

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

Доступность (a11y) — это практика создания сайтов, которые могут использовать люди с ограниченными возможностями. Это не только правильный поступок, но и требование закона во многих странах.

Кто использует доступные сайты?

  • Люди с нарушениями зрения (используют скринридеры)
  • Люди с нарушениями слуха (нужны субтитры для видео)
  • Люди с ограниченной подвижностью (используют только клавиатуру)
  • Пожилые люди (могут иметь проблемы с мелким текстом)
  • Люди с когнитивными нарушениями (нужна простая навигация)

Семантические HTML теги

Семантические теги — это основа доступности. Они помогают скринридерам понять структуру страницы.

<!-- ✅ Хорошо -->
<header>
  <nav>
    <ul>
      <li><a href="#home">Главная</a></li>
    </ul>
  </nav>
</header>

<main>
  <article>
    <h1>Заголовок статьи</h1>
    <p>Текст статьи...</p>
  </article>
</main>

<footer>
  <p>Копирайт</p>
</footer>

<!-- ❌ Плохо -->
<div class="header">
  <div class="nav">
    <div><div>Главная</div></div>
  </div>
</div>

Почему семантические теги важны? Скринридеры используют их для навигации. Пользователь может перейти к <main>, пропустив навигацию, или найти все <article> на странице.

Правильная структура заголовков

Заголовки должны идти по порядку (h1 → h2 → h3), без пропусков:

<!-- ✅ Правильно -->
<h1>Главный заголовок страницы</h1>
  <h2>Подзаголовок раздела</h2>
    <h3>Подзаголовок подраздела</h3>
  <h2>Другой раздел</h2>

<!-- ❌ Неправильно -->
<h1>Заголовок</h1>
<h3>Пропущен h2!</h3>
<h5>Пропущены h2, h3, h4!</h5>

Правила:

  • На странице должен быть только один <h1>
  • Не пропускайте уровни (h1 → h3 без h2 — плохо)
  • Используйте заголовки для структуры, а не для стилизации

Alt текст для изображений

Все изображения должны иметь атрибут alt с описанием:

<!-- ✅ Хорошо -->
<img src="cat.jpg" alt="Рыжий кот сидит на подоконнике">

<!-- ✅ Декоративное изображение -->
<img src="decoration.png" alt=""> <!-- Пустой alt для декоративных -->

<!-- ❌ Плохо -->
<img src="cat.jpg"> <!-- Нет alt -->
<img src="cat.jpg" alt="изображение"> <!-- Бесполезный alt -->

Правила для alt:

  • Описывайте содержимое изображения
  • Будьте конкретны, но кратки
  • Для декоративных изображений используйте пустой alt (alt="")
  • Не начинайте с "Изображение..." — скринридер сам скажет "изображение"

ARIA атрибуты

ARIA (Accessible Rich Internet Applications) — это набор атрибутов, которые делают сайт более доступным, когда семантических тегов недостаточно.

aria-label

<button aria-label="Закрыть модальное окно">×</button>
<button aria-label="Добавить товар в корзину">+</button>

Добавляет текстовое описание для скринридеров, когда видимый текст недостаточен.

aria-hidden

<span aria-hidden="true">✨</span>
<span class="sr-only">Иконка дизайна</span>

Скрывает декоративные элементы от скринридеров.

role

<div role="button" tabindex="0">Нажми меня</div>
<div role="alert">Важное сообщение</div>

Указывает роль элемента, когда семантический тег недоступен.

aria-expanded

<button aria-expanded="false" aria-controls="menu">Меню</button>
<ul id="menu" hidden>...</ul>

Показывает, развёрнут ли элемент (для аккордеонов, выпадающих меню).

Навигация с клавиатуры

Все интерактивные элементы должны быть доступны с клавиатуры:

  • Tab — переход к следующему элементу
  • Shift+Tab — переход к предыдущему элементу
  • Enter/Space — активация элемента (кнопка, ссылка)
  • Escape — закрытие модальных окон, меню
  • Стрелки — навигация в меню, слайдерах

tabindex

<!-- ✅ Обычные интерактивные элементы доступны автоматически -->
<button>Кнопка</button>
<a href="#">Ссылка</a>

<!-- ✅ Делаем div доступным с клавиатуры -->
<div role="button" tabindex="0">Нажми меня</div>

<!-- ❌ Убираем из навигации (но элемент остаётся видимым) -->
<button tabindex="-1">Недоступно с клавиатуры</button>

Значения tabindex:

  • 0 — элемент доступен с клавиатуры (в порядке DOM)
  • -1 — элемент недоступен с клавиатуры
  • Положительные числа — не рекомендуется (нарушает естественный порядок)

Focus стили

Все элементы должны иметь видимый focus стиль:

button:focus,
a:focus,
input:focus {
  outline: 2px solid #F36049;
  outline-offset: 2px;
}

/* Или более красивый вариант */
button:focus-visible {
  outline: 2px solid #F36049;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(243, 96, 73, 0.2);
}

Важно: Не убирайте outline без замены! Это критично для навигации с клавиатуры.

Контрастность цветов

Текст должен быть читаемым. Минимальный контраст:

  • Обычный текст: 4.5:1
  • Крупный текст (18px+): 3:1

Как проверить:

  • Используйте инструменты проверки контраста (WebAIM Contrast Checker)
  • Или DevTools — в панели Elements есть проверка контраста

Формы и доступность

Формы должны быть правильно связаны с label:

<!-- ✅ Правильно -->
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>

<!-- ✅ Или обёртка -->
<label>
  Email:
  <input type="email" name="email" required>
</label>

<!-- ❌ Плохо -->
<div>Email:</div>
<input type="email"> <!-- Нет связи с label -->

Сообщения об ошибках:

<label for="email">Email:</label>
<input type="email" id="email" aria-invalid="true" aria-describedby="email-error">
<span id="email-error" role="alert">Введите корректный email</span>

Скрытый текст для скринридеров

Иногда нужно скрыть текст визуально, но оставить для скринридеров:

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

<button>
  <span class="icon" aria-hidden="true">                    

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.