Практическое руководство по достижению соответствия WCAG AA на сайте Astro
Содержание
- Введение
- aria-hidden для декоративных иконок
- Решение
- Уведомления экранных читалок для внешних ссылок
- Решение
- Обеспечение контрастности
- Типичная проблема
- Решение
- Стили focus-visible
- Реализация с UnoCSS
- Часто упускаемые элементы
- Подчёркивание встроенных ссылок
- Решение
- Доступность форм
- Встроенная валидация
- Маркеры обязательных полей
- Атрибут role для элементов figure
- Атрибут role для элементов списков
- Другие улучшения
- Атрибуты width/height для изображений
- aria-live на слайдере главной страницы
- aria-labelledby на dialog
- aria-current на пагинации
- Обновление aria-label кнопки копирования
- Заключение
- Серия статей
Введение
«Доступность» может показаться чем-то, что легко отложить на потом. Но когда вы начинаете работать над ней, то осознаёте, что улучшение контрастности, навигации с клавиатуры и индикаторов фокуса напрямую повышает удобство использования для каждого пользователя.
В этой статье представлены улучшения, сделанные для достижения оценки доступности PageSpeed 100 на сайте Astro + UnoCSS, организованные по категориям.
aria-hidden для декоративных иконок
Иконки UnoCSS Iconify (i-lucide-*) часто используются как визуальное украшение, но когда экранные читалки их озвучивают, они объявляют «изображение» или «неизвестное изображение», что вызывает путаницу.
Решение
Добавьте aria-hidden="true" к декоративным иконкам.
<span class="i-lucide-mail" aria-hidden="true"></span>
Контакты
Это было применено к более чем 30 иконкам по всему сайту. Будьте внимательны, чтобы не пропустить иконки внутри компонентов StatBar, Callout, ServiceCard и ProcessFigure.
Уведомления экранных читалок для внешних ссылок
Внешние ссылки, открываемые с target="_blank", визуально показывают, что они открываются в новой вкладке, но это не передаётся пользователям экранных читалок.
Решение
Добавьте визуально скрытый поясняющий текст к внешним ссылкам.
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
Пример
<span class="sr-only">(открывается в новой вкладке)</span>
</a>
С помощью плагина rehype-external-links можно автоматически добавлять target="_blank" и rel к внешним ссылкам в Markdown. Текст уведомления для экранных читалок добавляется на стороне шаблона.
Обеспечение контрастности
Недостаточная контрастность — самая распространённая проблема, выявляемая PageSpeed Insights.
Типичная проблема
Использование text-slate-400 из цветовой палитры UnoCSS даёт коэффициент контрастности около 3:1 на белом фоне, что не соответствует требованию WCAG AA 4,5:1.
Решение
Изменение text-slate-400 → text-slate-500 (коэффициент контрастности 4,6:1) решает проблему. Это часто используется для вспомогательного текста, такого как даты и подписи, поэтому проверьте весь сайт.
Стили focus-visible
Для пользователей, которые навигируют по сайтам с клавиатуры, индикаторы фокуса — единственный способ узнать, «где я сейчас нахожусь». WCAG 2.4.7 требует видимости фокуса.
Реализация с UnoCSS
Установите общие стили фокуса для кнопок и ссылок. Используя функцию shortcuts в UnoCSS, можно определить их в одном месте и применять повсюду.
shortcuts: {
'ac-btn': '... focus-visible:ring-2 focus-visible:ring-brand-500 focus-visible:ring-offset-2 focus-visible:outline-none',
}
focus-visible — это псевдокласс, который показывает кольцо только при навигации с клавиатуры, а не при клике мышью. Он обеспечивает лучший UX, чем focus, поэтому используйте именно его.
Часто упускаемые элементы
- Кнопки копирования
- Кнопка прокрутки вверх
- Кнопка закрытия якорной рекламы
- Кнопки закрытия модальных окон
Подчёркивание встроенных ссылок
PageSpeed может отметить «Ссылки идентифицируются только по цвету». Это проблема для пользователей с нарушениями цветового зрения, которые не могут различить ссылки.
Решение
Сделайте подчёркивание постоянно видимым, а не только при наведении. Для единообразия рекомендуется использовать shortcuts UnoCSS.
shortcuts: {
'ac-link': 'underline decoration-brand-300 underline-offset-2 hover:decoration-brand-500 transition-colors',
}
Доступность форм
Доступность особенно важна там, где пользователи вводят данные, например в контактных формах.
Встроенная валидация
Отображайте сообщения об ошибках немедленно при событиях blur/input, координируя со следующими aria-атрибутами:
aria-invalid="true"— уведомляет, что ввод недействителенaria-describedby— ссылается на ID сообщения об ошибке
<input
type="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error" role="alert">Пожалуйста, введите корректный адрес электронной почты</p>
Маркеры обязательных полей
Одного визуального знака * недостаточно. Добавьте поясняющий текст для экранных читалок.
<span aria-hidden="true">*</span>
<span class="sr-only">(обязательно)</span>
Атрибут role для элементов figure
Установка role="img" на элементах <figure> скрывает дочерние элементы от экранных читалок. Для компонентов, содержащих иконки и описательный текст (InsightGrid, ProcessFigure, Timeline), измените на role="group", чтобы сохранить доступность внутреннего содержимого.
Атрибут role для элементов списков
Когда применяется CSS list-style: none, экранная читалка Safari (VoiceOver) имеет известную ошибку — она перестаёт распознавать элемент как список.
Добавьте role="list" к элементам <ol> / <ul> в хлебных крошках, боковых панелях и подвалах. Проверьте все списки с изменённым внешним видом.
Другие улучшения
Атрибуты width/height для изображений
Изображения без явных width и height вызывают сдвиги макета (CLS — Cumulative Layout Shift) при завершении загрузки. Укажите размеры для всех изображений, включая аватары (32×32, 48×48, 64×64px) и миниатюры YouTube (480×360px).
aria-live на слайдере главной страницы
Автоматически вращающиеся слайдеры не сообщают об изменениях пользователям экранных читалок. Подготовьте область с aria-live="polite" и уведомляйте текстом вроде «Слайд 1 / 4: [заголовок]».
aria-labelledby на dialog
Укажите ID элемента заголовка через aria-labelledby на элементах <dialog>, чтобы экранные читалки могли озвучить назначение модального окна.
aria-current на пагинации
Установите aria-current="page" на текущем номере страницы, чтобы уведомить экранные читалки о том, что это «текущая страница».
Обновление aria-label кнопки копирования
При успешном копировании в буфер обмена динамически обновляйте aria-label на «Скопировано», чтобы уведомить экранные читалки об изменении состояния.
Заключение
Улучшения доступности — это небольшие отдельные изменения, но вместе они значительно повышают общее качество сайта. Три самых значимых изменения:
- Глобальное применение focus-visible: кардинально улучшило навигацию с клавиатуры
- Исправление коэффициентов контрастности: простая замена
text-slate-400→text-slate-500обеспечила соответствие WCAG AA - Уведомления экранных читалок для внешних ссылок: в сочетании с
rehype-external-linksобеспечивают автоматическое покрытие всех ссылок
Начните со сканирования вашего сайта с помощью axe DevTools и устраните сначала автоматически обнаруживаемые проблемы.
Серия статей
Эта статья является частью серии «Руководство по улучшению качества сайта на Astro». Отдельные статьи также посвящены улучшению производительности, SEO и UX.
Рабочий процесс улучшения доступности
Автоматическое тестирование
Используйте axe DevTools и Lighthouse для выявления автоматически обнаруживаемых проблем.
Ручное тестирование
Попробуйте самостоятельно навигацию с клавиатуры и экранной читалкой.
Исправление
Добавьте aria-атрибуты, исправьте контрастность и добавьте стили фокуса.
Повторное тестирование
Убедитесь, что оценка доступности PageSpeed равна 100.
- Выполнено: Контрастность текста 4,5:1 или выше (3:1 для крупного текста)
- Выполнено: Все интерактивные элементы имеют стили focus-visible
- Выполнено: Декоративные иконки имеют aria-hidden="true"
- Выполнено: Внешние ссылки имеют уведомления для экранных читалок
- Выполнено: Формы имеют встроенную валидацию с интеграцией aria-invalid
- Выполнено: Изображения имеют атрибуты width/height (предотвращение CLS)
- Выполнено: Элементы списков имеют role="list" (обходное решение для list-style:none)
В чём разница между axe DevTools и Lighthouse?
Нужно ли добавлять aria-атрибуты к каждому элементу?
Означает ли оценка доступности PageSpeed 100 соответствие WCAG?
Gui
Генеральный директор Acecore. Универсальный инженер, охватывающий разработку систем, веб-производство, управление инфраструктурой и IT-образование. Любит решать организационные и человеческие задачи с помощью технологий.
Хотите узнать больше о наших услугах?
Мы обеспечиваем комплексную поддержку: разработка систем, веб-дизайн, графический дизайн и IT-образование.