Чек-лист доступности сайта для разработчика
Практика3 минРедакция Innovialabs
Коротко
Проверьте, что всё работает с клавиатуры и фокус виден, у изображений и полей есть текстовые названия, контраст достаточный, разметка семантическая, анимация уважает reduced motion, а затем прогоните axe и screen reader.
Главное за минуту
Большинство проблем доступности решается на уровне обычной вёрстки, без сложных библиотек. Минимальный набор проверок:
- Всё управляется с клавиатуры, и фокус виден.
- У изображений есть alt, у полей — label, у кнопок-иконок — доступное имя.
- Контраст текста и элементов интерфейса достаточный.
- Разметка семантическая: заголовки по порядку, landmarks, настоящие кнопки и ссылки.
- Анимация учитывает prefers-reduced-motion.
- Результат проверен axe и экранным диктором.
Ниже — подробно по каждому пункту.
Клавиатура и фокус
- Все интерактивные элементы доступны по Tab, порядок совпадает с визуальным.
- Кнопки — это
<button>, ссылки —<a href>.divсonClickнедоступен с клавиатуры. - Нет
tabindexбольше 0 — он ломает естественный порядок. - Модальные окна удерживают фокус внутри, закрываются по Esc и возвращают фокус на кнопку, которая их открыла.
- Есть ссылка «Перейти к содержимому» в начале страницы.
- Фокус никогда не скрыт через
outline: noneбез замены.
:focus-visible {
outline: 2px solid #7c3aed;
outline-offset: 2px;
}
:focus-visible показывает рамку при навигации с клавиатуры и не мешает при клике мышью.
Изображения и медиа
- Информативные изображения имеют осмысленный
alt, описывающий смысл, а не «картинка». - Декоративные изображения —
alt="", чтобы диктор их пропускал. - Иконки внутри кнопок скрыты (
aria-hidden="true"), а у кнопки есть текст илиaria-label. - У видео есть субтитры, у аудио — расшифровка.
- Автовоспроизведение со звуком отключено.
Формы
- У каждого поля есть
<label>, связанный черезforиid. Placeholder не заменяет label. - Обязательные поля отмечены не только цветом.
- Ошибки показаны текстом рядом с полем и связаны с ним через
aria-describedby. - Для полей указан
autocomplete(имя, email, телефон) — это помогает и людям с моторными ограничениями.
<label for="email">Email</label>
<input id="email" type="email" autocomplete="email"
aria-describedby="email-error" aria-invalid="true">
<p id="email-error">Введите email в формате name@example.com</p>
Контраст и цвет
- Обычный текст — контраст не ниже 4.5:1, крупный текст — не ниже 3:1 (уровень WCAG AA).
- Границы полей, иконки и состояния фокуса — не ниже 3:1 к фону.
- Информация не передаётся только цветом: ошибка — это красная рамка плюс текст или иконка.
- Текст читается при увеличении до 200% и не обрезается.
Семантика и landmarks
- Один
<h1>на странице, заголовки идут по уровням без пропусков. - Используются
<header>,<nav>,<main>,<footer>— по ним диктор быстро перемещается. - Указан язык страницы:
<html lang="ru">. - Списки — это
<ul>/<ol>, таблицы с данными —<table>с<th>. - Ссылки понятны без контекста: не «здесь», а «Скачать прайс».
Анимация и движение
- Нет мигания чаще трёх раз в секунду.
- Автоматически движущийся контент можно поставить на паузу.
- Крупные анимации отключаются при системной настройке уменьшения движения:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Тестирование
| Инструмент | Что находит |
|---|---|
| axe DevTools / Lighthouse | Отсутствующие alt и label, низкий контраст, ошибки ARIA |
| Клавиатура | Ловушки фокуса, невидимый фокус, недоступные элементы |
| Screen reader (NVDA, VoiceOver, TalkBack) | Непонятные названия, неверный порядок чтения, немые кнопки |
| Масштаб 200% и мобильная ширина | Обрезанный текст, горизонтальная прокрутка |
Добавьте автоматические проверки в CI — например, через @axe-core/playwright в end-to-end тестах, — но не считайте их полной заменой ручной проверки.