UX-доступность и интерфейсы для всех
1) Зачем это важно
Юридически и этически: интерфейс не должен исключать людей с нарушениями зрения, слуха, моторики, когнитивных особенностей.
Бизнес-эффект: больше пользователей, выше конверсия и удержание, лучше SEO и качество кода.
Операционно: доступность — это процесс, а не «случайный фикс».
2) Основы и принципы (POUR)
Perceivable (Воспринимаемость): контраст, тексты-альтернативы, субтитры.
Operable (Управляемость): все доступно с клавиатуры, видимый фокус, пауза/стоп анимаций.
Understandable (Понятность): предсказуемая навигация, ясные ошибки, простые формулировки.
Robust (Надежность): корректная семантика HTML/ARIA, совместимость с ассистивными технологиями.
3) Семантика, заголовки и ARIA
Семантическая разметка прежде ARIA: `<button>`, `<nav>`, `<form>`, `<table>` — по назначению.
Иерархия заголовков: один `<h1>` на страницу, далее логичная структура `<h2>`–`<h3>`.
Landmarks: `<header>`, `<main>`, `<aside>`, `<footer>`, `<nav>` — помогают скринридерам.
ARIA только при необходимости: `role`, `aria-label`, `aria-describedby`, `aria-expanded`, `aria-live`.
Состояния/ошибки через `aria-invalid`, `aria-errormessage`.
4) Клавиатура и фокус-менеджмент
Полная управляемость клавиатурой: `Tab/Shift+Tab` — порядок, `Enter/Space` — активировать, `Esc` — выход.
Видимый фокус всегда; не отключать outline.
Ловушки фокуса: в модалках — циклический фокус, возврат фокуса на источник после закрытия.
Скрытые элементы не должны попадать в таб-порядок (`display:none`, `aria-hidden="true"`).
Скип-ссылки: «Перейти к основному содержимому» — в начале страницы.
5) Цвет, контраст и типографика
Контраст текста: не менее 4.5:1 для обычного текста и 3:1 для крупного.
Не полагаться только на цвет: дублируйте иконкой/паттерном/подписью.
Размер кликабельных целей: минимум 40–48 px, достаточные поля вокруг.
Шрифты: читаемые гарнитуры, межстрочный 1.4–1.6, длина строки 45–90 знаков.
6) Движение, анимации и эпилептогенная вспышка
Уважайте системный флаг prefers-reduced-motion — добавляйте упрощенные анимации/отключайте параллакс.
Избегайте мерцаний > 3 раз/сек.
Все авто-движения должны иметь Pause/Stop/Hide.
7) Формы, ошибки и валидация
Явно связывайте метки и поля: `<label for="id">`.
Плейсхолдер — не метка.
Сообщения об ошибках рядом с полем и в сводке ошибок вверху; связывайте через `aria-describedby`.
Поясняйте формат ввода, пример, маску; указывайте единицы и валюту.
Не сбрасывайте заполненные поля при ошибке; сохраняйте фокус на проблемном поле.
html
<label for="email">Эл. почта</label>
<input id="email" name="email" type="email" aria-describedby="email-hint email-err">
<div id="email-hint" class="hint">Мы не рассылаем спам</div>
<div id="email-err" class="error" role="alert">Укажите адрес в формате name@example.com</div>
8) Компоненты и интерактив: паттерны
Кнопки vs ссылки: действие = `<button>`, переход = `<a>`.
Табы/аккордеоны: стрелки навигации, `aria-controls`, `aria-selected`.
Модалки/диалоги: `role="dialog"`, `aria-modal="true"`, ловушка фокуса, `Esc` закрывает.
Tooltip/Popover: доступность по клавиатуре, таймауты не мешают чтению.
Drag & Drop: альтернативы — кнопки «переместить вверх/вниз», клавиатурные стрелки; события не только мышью.
9) Медиа: видео/аудио/графики
Видео: субтитры, расшифровка (transcript), альтернативная дорожка аудио-описаний (AD).
Аудио: текстовая расшифровка.
Графики/диаграммы: текстовое резюме («что важно»), таблица данных, описательные подписи осей.
Живые области: `aria-live="polite"/"assertive"` — осторожно, чтобы не «кричать» слишком часто.
10) Таблицы и списки
11) i18n, локали и RTL
Атрибут `lang` на html-корне; локальные форматы чисел/дат/валют.
RTL поддержка (арабский/иврит): зеркалирование иконок, порядок навигации, курсоров.
Избегайте вшитых в иконки слов (текст должен быть переводимым).
Простые формулировки, избегать жаргона; глоссарий терминов.
12) Время, сессии, капчи и альтернативы
Таймауты — с предупреждением и возможностью продлить.
CAPTCHA: предпочитайте альтернативы (вопросы, невидимые анализаторы ботов, подтверждение по почте/телефону); если используете — текстовую альтернативу и не только визуальную.
Аутентификация: поддержка менеджеров паролей, «показать пароль», WebAuthn.
13) Доступность для сенсорных и моторных нарушений
Жесты должны иметь эквиваленты клику/клавиатуре.
Не требуйте длительных удержаний/двойных тапов без альтернативы.
«Pointer cancellation»: действие должно выполняться на отпускание, не на «нажатие», чтобы дать шанс отменить.
14) Состояния, уведомления и алерты
Используйте `role="status"/"alert"` для динамических сообщений.
Не перекрывайте фокус «липкими» баннерами.
Toast-уведомления — с паузой при фокусе/hover и доступом с клавиатуры.
15) Тест-план (ручной и авто)
Ручной (минимум):- Пройти все ключевые сценарии только клавиатурой.
- Проверить видимость фокуса на каждом элементе.
- Увеличить масштаб до 200% — интерфейс остается функциональным без горизонтального скролла.
- Включить системный режим «уменьшение движения» — анимации не мешают.
- Пройти сценарий со скринридером (NVDA/VoiceOver), убедиться в правильных ролях/метках/порядке.
- Линты доступности на уровне компонентов.
- Проверка контраста, альтернативных текстов, порядка заголовков, валидности ARIA.
- Снапшоты семантики (role tree) для критичных экранов.
16) Метрики качества доступности
A11y Coverage: доля компонентов с пройденными чек-листами.
Keyboard-only Pass Rate: процент сценариев, проходимых клавиатурой.
Contrast Violations / 1k элементов.
SR Flow Time: время прохождения сценария со скринридером.
User-feedback: жалобы на доступность, время реакции и исправления.
17) Чек-лист компонента
- Правильная семантика/роль без избыточной ARIA
- Подписанные метки, `aria-` корректны
- Полная управляемость клавиатурой, видимый фокус
- Контраст текста/иконок/границ в норме
- Ошибки и состояния озвучиваются скринридером
- Уважение prefers-reduced-motion
- Размер кликабельной области ≥ 40–48 px
- Локализация и RTL не ломают макет
18) Анти-паттерны
«Див-кнопки» без роли/клавиатуры.
Скрытие фокуса `outline: none` без альтернативы.
Плейсхолдер вместо label.
Ошибки только цветом.
Модалки без ловушки фокуса и без `Esc`.
Drag-only без клавиатуры.
Длинные автопрокрутки/параллакс без опции отключить.
19) Роли и процесс
A11y-владелец в команде (Product/Design/Dev).
Дефинишн-оф-дан (DoD) включает доступность.
Дизайн-ревью: проверка контраста, фокуса, лейблов.
Код-ревью: семантика/ARIA, тест клавиатурой.
Регулярные аудиты и план улучшений.
20) Внедрение по итерациям
Итерация 1 — Фундамент (2 недели):- Семантика/заголовки, контраст, фокус и клавиатура, базовые формы и ошибки.
- Модалки, табы/аккордеоны, таблицы/графики с текстовым резюме, видео-субтитры, сниженная анимация.
- Автотесты в CI, RTL/i18n, метрики, регулярные аудиты, обучение команды.
21) Шаблоны и сниппеты
Модалка (упрощенно):html
<div role="dialog" aria-modal="true" aria-labelledby="dlg-title" aria-describedby="dlg-desc">
<h2 id="dlg-title">Подтвердите действие</h2>
<p id="dlg-desc">Эта операция необратима.</p>
<button>Отмена</button>
<button>Подтвердить</button>
</div>
Кнопка «пропустить к содержимому»:
html
<a class="skip-link" href="#main">Перейти к основному содержимому</a>
<main id="main">...</main>
Уважение prefers-reduced-motion:
css
@media (prefers-reduced-motion: reduce) {
{ animation-duration: 0.01ms!important; animation-iteration-count: 1!important; transition: none!important; }
}
22) Мини-FAQ
Нужна ли отдельная «версия для слабовидящих»?
Нет. Одна адаптивная, доступная версия для всех с настройками.
Достаточно ли проверить только контраст?
Нет. Контраст — лишь часть. Нужны клавиатура, фокус, семантика, форм-ошибки, медиа и т. д.
ARIA решит все?
ARIA не исправит неверную семантику. Сначала правильные теги, затем ARIA-уточнения.
Итог
Доступность — это системная дисциплина: семантика → клавиатура/фокус → контраст/цвет → формы/ошибки → медиа/графики → i18n/RTL → тест-план и метрики. Делайте доступность частью DoD и культуры команды — и ваш продукт станет по-настоящему универсальным, надежным и удобным для всех.