Аудит и улучшение веб-доступности: автоматические проверки, ручное тестирование и конкретные исправления.
npx -y skills add addyosmani/web-quality-skills --skill accessibility --agent claude-codeКомплексные рекомендации по доступности на основе WCAG 2.2 и аудитов Lighthouse. Цель: сделать контент доступным для всех, включая людей с ограниченными возможностями. Используйте при запросах «улучшить доступность», «a11y аудит», «WCAG compliance», «поддержка screen reader», «навигация с клавиатуры».
| Принцип | Описание |
|---|---|
| Perceivable (Воспринимаемость) | Контент воспринимается через разные органы чувств |
| Operable (Управляемость) | Интерфейсом можно управлять любым способом |
| Understandable (Понятность) | Контент и интерфейс понятны пользователю |
| Robust (Надёжность) | Контент работает со вспомогательными технологиями |
| Уровень | Требование | Цель |
|---|---|---|
| A | Минимальная доступность | Обязательно |
| AA | Стандартное соответствие | Рекомендуется (требуется по закону во многих юрисдикциях) |
| AAA | Расширенная доступность | Желательно |
<!-- Описательный alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales">
<!-- Декоративное изображение (пустой alt) -->
<img src="decorative.png" alt="" role="presentation">
<!-- Кнопка с иконкой — доступное имя через aria-label -->
<button aria-label="Open menu">
<svg aria-hidden="true"><!-- иконка --></svg>
</button>
Класс для визуально скрытых элементов:
.visually-hidden {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
| Размер текста | AA минимум | AAA расширенный |
|---|---|---|
| Обычный (<18px / <14px жирный) | 4.5:1 | 7:1 |
| Крупный (≥18px / ≥14px жирный) | 3:1 | 4.5:1 |
| UI компоненты и графика | 3:1 | 3:1 |
/* Состояние фокуса с достаточным контрастом (WCAG 1.4.11) */
:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
}
Не полагайтесь только на цвет для передачи информации — добавляйте иконки или текст.
<video controls>
<source src="video.mp4" type="video/mp4">
<track kind="captions" src="captions.vtt" srclang="en" label="English" default>
</video>
<!-- Аудио с транскриптом -->
<audio controls><source src="podcast.mp3"></audio>
<details>
<summary>Транскрипт</summary>
<p>Текст транскрипта...</p>
</details>
Весь функционал должен быть доступен с клавиатуры. Предпочитайте нативные интерактивные элементы — <button>, <a href>, поля форм — они обрабатывают Enter/Space, фокус и семантику для вспомогательных технологий автоматически.
<!-- Нативная кнопка — лучший вариант -->
<button type="button" onclick="handleAction()">Открыть</button>
<!-- Если НЕОБХОДИМО использовать нативный элемент с role="button" -->
element.setAttribute('role', 'button');
element.setAttribute('tabindex', '0');
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleAction();
}
});
<!-- Пропуск к основному контенту -->
<a href="#main-content" class="skip-link">Перейти к основному контенту</a>
/* Видим только при фокусе */
.skip-link { position: absolute; transform: translateY(-100%); }
.skip-link:focus { transform: translateY(0); }
Порядок фокуса должен следовать логическому порядку чтения. Используйте tabindex="0" для добавления элемента в порядок фокуса, tabindex="-1" — для программного фокуса без добавления в порядок. Никогда не убирайте видимый фокус без CSS-альтернативы.
<!-- Модальный диалог -->
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title" aria-describedby="dialog-desc">
<h2 id="dialog-title">Подтвердить удаление</h2>
<p id="dialog-desc">Это действие нельзя отменить.</p>
<button>Удалить</button>
<button>Отмена</button>
</div>
<!-- Live region для динамических обновлений -->
<div aria-live="polite" aria-atomic="true">
Показано результатов: 42
</div>
<div class="field-error">
<label for="email">Email</label>
<input id="email" type="email" aria-invalid="true" aria-describedby="email-error"
aria-required="true">
<span id="email-error" role="alert">
Введите корректный email
</span>
</div>
<!-- Структура страницы -->
<header><nav aria-label="Основная навигация"></nav></header>
<main id="main-content">
<article></article>
<aside aria-label="Связанные материалы"></aside>
</main>
<footer></footer>
| Инструмент | Применение |
|---|---|
| axe DevTools | Автоматическое обнаружение нарушений |
| WAVE | Визуализация проблем доступности |
| Lighthouse | Автоматический аудит в Chrome DevTools |
| NVDA / VoiceOver | Ручное тестирование со screen reader |
| Contrast Checker | Проверка контрастности (WebAIM) |
lang