Как сделать описание доступным: aria-describedby и HTML-разметка
#Основы HTML #Теги и атрибуты #Доступность (ARIA)Для кого эта статья:
- веб-разработчики и дизайнеры
- специалисты по доступности интерфейсов
- менеджеры продуктов и UX-исследователи
Когда элемент управления на вашем сайте вызывает у пользователей недоумение, это уже проблема. Но для людей, использующих скринридеры, такая ситуация может полностью блокировать взаимодействие с интерфейсом. Атрибут aria-describedby — один из самых мощных инструментов, позволяющих связать элементы с их описаниями и сделать пользовательский опыт по-настоящему инклюзивным. В этой статье мы разберем, как правильно использовать этот атрибут, чтобы ваш интерфейс был понятен каждому — от опытного пользователя до человека с ограниченными возможностями. 🔍
Значение aria-describedby в создании доступных интерфейсов
Представьте себе ситуацию: пользователь с нарушением зрения заполняет форму регистрации. Он натыкается на поле для ввода пароля, но скринридер просто сообщает "Введите пароль". Никаких требований, никаких подсказок о необходимой длине или специальных символах. В результате — ошибки валидации и разочарование.
Атрибут aria-describedby решает именно эту проблему. Он создает семантическую связь между элементом управления и текстом, который его описывает. Когда скринридер фокусируется на элементе с этим атрибутом, он не только озвучивает его название (через label или aria-label), но и дополнительное описание.
Марина Коровина, руководитель команды по доступности
Недавно к нам обратился клиент из банковского сектора, который столкнулся с неожиданной проблемой: 30% пользователей с нарушениями зрения покидали форму открытия счета, не завершив процесс. Оказалось, что сложные правила для полей не были доступны для скринридеров — визуально подсказки отображались, но программно они не были связаны с полями ввода. После внедрения
aria-describedbyкоэффициент успешных регистраций вырос на 18% всего за первый месяц. Это наглядно демонстрирует, как простое техническое решение может значительно улучшить пользовательский опыт.
Стандарты WCAG (Web Content Accessibility Guidelines) не просто рекомендуют — они требуют, чтобы пользователи получали контекстную информацию о полях ввода. Согласно критерию успеха 3.3.2 (уровень A), если элемент формы требует ввода в определенном формате, это должно быть явно указано.
| Критерий WCAG | Требование | Решение с aria-describedby |
|---|---|---|
| 3.3.2 Метки или инструкции (Уровень A) | Предоставление инструкций для ввода данных | Связывание поля с текстом инструкции |
| 3.3.1 Выявление ошибок (Уровень A) | Идентификация ошибок ввода | Связывание поля с сообщением об ошибке |
| 1.3.1 Информация и взаимосвязи (Уровень A) | Программное определение отношений между элементами | Явная программная связь между полем и описанием |
Важно понимать, что aria-describedby — это не просто "хорошая практика". Это фундаментальный инструмент для создания по-настоящему инклюзивных интерфейсов, и его отсутствие может сделать ваш сайт непреодолимым барьером для значительной части пользователей.

Связывание элементов с помощью атрибута aria-describedby
Технически aria-describedby устанавливает программную связь между элементом интерфейса и его описанием через ID. Когда ассистивные технологии, такие как скринридеры, обнаруживают этот атрибут, они озвучивают связанное описание после основной метки элемента.
Базовый синтаксис выглядит следующим образом:
<input id="username" aria-describedby="username-help" type="text">
<div id="username-help">Имя пользователя должно содержать от 5 до 12 символов</div>
В этом примере скринридер сначала прочитает метку поля ввода (если она указана через <label>), а затем дополнительное описание из элемента с id="username-help".
Вы можете связать элемент с несколькими описаниями, перечислив несколько ID через пробел:
<input
id="password"
aria-describedby="password-requirements password-tip"
type="password"
>
<div id="password-requirements">Пароль должен содержать не менее 8 символов, включая цифры и специальные символы</div>
<div id="password-tip">Подсказка: используйте комбинацию букв, цифр и символов для создания надежного пароля</div>
Существует несколько ключевых правил при использовании aria-describedby:
- Описание должно быть лаконичным и информативным — скринридеры зачитывают весь связанный текст.
- Целевой элемент (с указанным ID) должен существовать на странице.
- Если описание не видимо визуально (например, с
display: none;), оно не будет озвучено. - Используйте класс
visually-hiddenвместоdisplay: none, если хотите скрыть элемент визуально, но сохранить его для скринридеров.
Важное практическое замечание: aria-describedby следует использовать для дополнительной информации, а не для основной метки элемента. Для обозначения основных меток используйте <label> или aria-label.
Практические способы применения aria-describedby в формах
Формы — это одна из самых критичных областей для применения атрибута aria-describedby, поскольку здесь пользователям часто требуется дополнительный контекст для правильного ввода данных. 📝
Алексей Правдин, фронтенд-разработчик
При разработке системы бронирования для крупной гостиничной сети мы столкнулись с необычной проблемой. Пользователи с нарушениями зрения регулярно вводили неверный формат телефона, что приводило к срыву бронирований. Интересно, что визуально формат был указан, но информация не считывалась скринридерами. Мы добавили
aria-describedbyк полю телефона, указав точный формат, и количество ошибок сократилось на 83%. Этот случай полностью изменил мой подход к разработке форм — теперь я всегда тестирую интерфейсы с отключенным экраном, используя только клавиатуру и скринридер.
Рассмотрим различные сценарии применения aria-describedby в контексте форм:
1. Описание требований к вводу
<label for="email">Email</label>
<input type="email" id="email" aria-describedby="email-format">
<span id="email-format">Введите действующий email в формате username@example.com</span>
2. Связывание с сообщениями об ошибках
<label for="phone">Телефон</label>
<input type="tel" id="phone" aria-describedby="phone-format phone-error">
<span id="phone-format">Формат: +7 (XXX) XXX-XX-XX</span>
<span id="phone-error" class="error">Неверный формат телефона</span>
3. Динамическое обновление описаний
Часто нам нужно динамически обновлять сообщения об ошибках. При этом важно сохранить связь через aria-describedby:
// Пример JavaScript для обновления сообщения об ошибке
function validatePassword(input) {
const errorElement = document.getElementById('password-error');
if (input.value.length < 8) {
errorElement.textContent = 'Пароль должен содержать не менее 8 символов';
input.setAttribute('aria-invalid', 'true');
} else {
errorElement.textContent = '';
input.removeAttribute('aria-invalid');
}
}
Вот сравнительная таблица различных сценариев использования aria-describedby:
| Сценарий | Описание | Пример реализации |
|---|---|---|
| Требования к паролю | Указание правил создания надежного пароля | aria-describedby="password-rules" |
| Сообщения об ошибках | Связывание поля с текстом ошибки валидации | aria-describedby="field-error" |
| Счетчики символов | Информация о лимите символов в поле | aria-describedby="char-count" |
| Комбинированные описания | Связывание с несколькими описаниями | aria-describedby="field-help field-error char-count" |
При разработке форм с использованием aria-describedby следует помнить несколько ключевых моментов:
- Всегда обновляйте содержимое описания, а не сам атрибут
aria-describedby. - Комбинируйте с другими атрибутами ARIA для полноты информации (
aria-required,aria-invalid). - Старайтесь размещать описания непосредственно после связанных полей для улучшения визуального контекста.
- Используйте краткие, но информативные описания — длинные тексты могут дезориентировать пользователя.
Оптимальная HTML-разметка для передачи контекстной информации
Грамотное использование aria-describedby требует продуманной HTML-структуры. Недостаточно просто добавить атрибут — необходимо создать семантически правильную разметку, которая будет эффективно работать как для зрячих пользователей, так и для пользователей ассистивных технологий.
Рассмотрим наиболее эффективные подходы к структурированию HTML-разметки для передачи контекстной информации:
1. Структура элементов формы с описаниями
<div class="form-group">
<label for="username">Имя пользователя</label>
<input
type="text"
id="username"
aria-describedby="username-help username-error"
aria-required="true"
>
<p id="username-help" class="help-text">
Используйте только буквы, цифры и символ подчеркивания
</p>
<p id="username-error" class="error-message" aria-live="polite"></p>
</div>
Обратите внимание на атрибут aria-live="polite" для сообщения об ошибке. Он обеспечивает динамическое оповещение скринридера о появлении ошибки, но не прерывает текущее чтение.
2. Группировка связанных элементов
Для логически связанных групп полей следует использовать <fieldset> и <legend>, дополняя их с помощью aria-describedby:
<fieldset aria-describedby="address-instructions">
<legend>Адрес доставки</legend>
<div id="address-instructions">
Все поля в этом разделе обязательны для заполнения
</div>
<div class="form-group">
<label for="street">Улица</label>
<input type="text" id="street" required>
</div>
<div class="form-group">
<label for="city">Город</label>
<input type="text" id="city" required>
</div>
</fieldset>
3. Скрытие визуальных элементов с сохранением доступности
Иногда нам нужно предоставить дополнительную информацию для скринридеров, но без визуального загромождения интерфейса. Для этого используйте специальный класс visually-hidden вместо display: none:
<style>
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
</style>
<label for="credit-card">Номер кредитной карты</label>
<input
type="text"
id="credit-card"
aria-describedby="cc-format cc-security-note"
>
<span id="cc-format">Формат: XXXX XXXX XXXX XXXX</span>
<span id="cc-security-note" class="visually-hidden">
Ваши данные защищены 256-битным шифрованием и никогда не передаются третьим лицам
</span>
При построении оптимальной HTML-разметки следует придерживаться нескольких принципов:
- Размещайте связанные элементы (поле и его описание) в непосредственной близости друг от друга.
- Используйте семантически правильные элементы HTML5 — они упрощают восприятие структуры страницы.
- Применяйте атрибут
aria-liveдля динамически обновляемых сообщений. - Избегайте дублирования информации — не повторяйте в
aria-describedbyто, что уже указано в метке. - Проверяйте, что ID в
aria-describedbyуникальны в рамках всей страницы.
Тестирование доступности с использованием скринридеров
Теория без практической проверки — лишь половина успеха. Разработчик, создающий доступные интерфейсы, должен регулярно тестировать их с помощью реальных ассистивных технологий. 🔊
Тестирование с помощью скринридеров позволяет убедиться, что ваша реализация aria-describedby действительно работает как задумано. Вот пошаговое руководство по проведению эффективного тестирования:
1. Выбор инструментов тестирования
Для комплексного тестирования рекомендуется использовать несколько скринридеров, поскольку они могут по-разному интерпретировать ARIA-атрибуты:
- NVDA — бесплатная программа для Windows, широко используемая реальными пользователями.
- VoiceOver — встроенный скринридер в macOS и iOS.
- JAWS — коммерческий скринридер, имеющий большую долю рынка среди пользователей с нарушениями зрения.
- TalkBack — встроенный скринридер в Android устройствах.
2. Методика тестирования
Для проведения эффективного тестирования следуйте этому плану:
- Проверьте, что скринридер корректно объявляет метку элемента.
- Убедитесь, что после метки скринридер зачитывает связанное описание.
- Для полей с несколькими описаниями проверьте, что все они озвучиваются.
- Протестируйте динамическое обновление описаний (например, появление сообщений об ошибках).
- Проверьте работоспособность в разных браузерах.
3. Распространенные проблемы и их решения
| Проблема | Возможная причина | Решение |
|---|---|---|
| Описание не озвучивается | Неверный ID или описание скрыто с помощью display: none | Проверьте соответствие ID и используйте класс visually-hidden вместо display: none |
| Описание озвучивается дважды | Дублирование информации в label и describedby | Убедитесь, что информация не повторяется в разных атрибутах |
| Динамические описания не обновляются | Отсутствие атрибута aria-live | Добавьте aria-live="polite" к элементу с динамическим содержимым |
| Скринридер зачитывает слишком много информации | Избыточное количество связанных описаний | Оптимизируйте количество и длину описаний |
4. Автоматизированное тестирование
Хотя ручное тестирование со скринридерами незаменимо, автоматизированные инструменты могут помочь выявить базовые проблемы:
- axe DevTools — расширение для браузера, которое анализирует страницу на соответствие стандартам доступности.
- Lighthouse — инструмент от Google, включающий проверку доступности.
- WAVE — веб-инструмент для оценки доступности сайтов.
Однако помните, что автоматизированные инструменты могут обнаружить только около 30% проблем с доступностью. Они не заменят реального тестирования со скринридерами.
5. Регрессионное тестирование
После внесения изменений в интерфейс всегда проводите повторное тестирование доступности. Даже небольшие изменения могут нарушить работу aria-describedby:
// Пример регрессионного теста с использованием Jest и Testing Library
test('поле имеет правильное описание для скринридеров', () => {
render(<MyFormComponent />);
const inputElement = screen.getByLabelText('Email');
expect(inputElement).toHaveAttribute(
'aria-describedby',
expect.stringContaining('email-format')
);
const descriptionElement = document.getElementById('email-format');
expect(descriptionElement).toBeInTheDocument();
expect(descriptionElement).not.toHaveStyle('display: none');
});
Aria-describedby — это не просто технический атрибут, а мощный инструмент для создания по-настоящему инклюзивных интерфейсов. Правильное его использование делает ваш сайт не просто "соответствующим стандартам", а действительно удобным для всех пользователей. Начните с малого — добавьте описания к критически важным элементам форм, проверьте их работу с помощью скринридера, и постепенно расширяйте охват. Помните: доступность — это не пункт в чеклисте, а непрерывный процесс совершенствования пользовательского опыта. И каждый шаг в этом направлении имеет значение.
Ксения Сорокина
веб-техредактор