Как сделать сообщения об ошибках доступными
Перевод “How to make error messages accessible” Hidde de Vries
В одном проекте я помогаю государственной организации перенести бланки их заявлений в веб-формат. По понятным причинам это сложные и подробные формы. Мы стараемся максимально упростить процесс работы с ними и там, где это возможно, указываем пользователям на неверно заполненные поля. В статье я расскажу, как реализовать этот функционал в соответствии с принципами доступности.
В общих чертах должно работать так: неверное заполнение поля вызывает сообщение об ошибке. Если вы хотите делать это доступно, обратите внимание на следующие детали: обнаружение ошибки, оповещение пользователя (скринридера) о добавлении контента, описание ошибки доступным, понятным языком. Ниже я расскажу, как улучшить представление форм в трех указанных аспектах.
Согласно WCAG 3.3.1 Error Identification
При автоматическом обнаружении ошибок определяется элемент, содержащий ошибку, и описание ошибки доводится до пользователя в виде текста.
Да, это можно запрограммировать
Прежде чем продолжить, небольшое замечание касательно JavaScript.
В былые времена сабмит формы вызывал перезагрузку страницы, если нужно —выводя сообщения ошибках после перезагрузки. В 2017 году это все еще неплохое решение. Но его можно значительно улучшить: предотвращать отправку формы и инициализировать оповещения на стороне клиента. Да и зачем вовсе ожидать сабмит? Достаточно показывать сообщение сразу, как только пользователь перешел к заполнению следующего поля.
Должны ли “доступные” веб-формы избегать JavaScript? Напротив. Нужно использовать его возможности. В сочетании с “серверным” подходом это гарантирует лучший из возможных результат.
Нет смысла повторять: старые-добрые HTML элементы — ключевой фактор в доступности форм. В статье я коснусь техник, связанных с ARIA, но запомните: первое правило ARIA — не использовать ARIA. Другими словами, если вы можете обойтись возможностями HTML, ARIA не нужно. Исключения касаются решений за пределами HTML, и генерируемые сообщения об ошибках — один из таких случаев. Тем не менее, обратите внимание, HTML5 имеет нативные инструменты для работы с таким функционалом. Если их достаточно для решения ваших задач, то ARIA-атрибуты, описанные в статье, не понадобятся. Изучите также constraint validation API, оно позволяет кастомизировать сообщения.
Указываем на поле с ошибкой
Полю формы, заполненному неверно, можно применить атрибут aria-invalid
. Убедитесь, чтобы программа следила за изменением значения этого поля и в нужным момент удаляла атрибут.
Кстати, это еще и удобная возможность выделить элемент визуально:
[aria-invalid] { border-color: red; }
Добавление/удаление aria-invalid
— способ сообщить об ошибке пользователям скринридеров. Атрибут обрабатывается устройствами с JAWS, NVDA и VoiceOver.
Доставляем сообщение об ошибке
Когда программа определяет неправильно заполненное поле, на страницу добавляется сообщение об ошибке. Убедитесь, что его просто увидеть: используйте для выделения цвета, иконки, границы. Хорошей практикой может считаться прямое указание в тексте — “Ошибка”, с которого начинается сообщение.
Чтобы быть уверенными, что сообщение прочитано скринридером, нужно гарантировать получение деревом доступности генерируемого контента.
Существует два относительно эквивалентных способа сделать это. Оба — через ARIA-атрибуты: live regions (aria-live
) и role="alert"
. Они добавляют в элемент в “живую область”, изменения внутри которой отслеживаются скринридерами. Появление/изменения контента — как раз такой случай. Обратите внимание, в этом случае элемент должен быть частью DOM уже на момент загрузки документа. Атрибуты обрабатываются VoiceOver и большинством версий JAWS и NVDA.
Работает это следующим образом:
- Пользователь неправильно заполняет поле №1 и переходит к полю №2;
- Программа обнаруживает ошибку, прочитывает сообщение об ошибке (либо указывает на нее в виде большого красного сообщения на экране);
- Тем временем пользователь находится на поле №2 и сам выбирает, вернуться к полю №1 сейчас или позже.
Live region
Чтобы сделать элемент частью live region, добавьте ему атрибут aria-live
. Он принимает несколько значений. Значения указывают синтезатору, когда озвучить содержимое нового контента: сразу или нет. В нашем случае сообщение должно быть зачитано сразу, поэтому используем aria-live="assertive"
:
<div aria-live="assertive">
<!-- добавляем сообщение об ошибке -->
</div>
Теперь мы отслеживаем некорректное заполнение полей, но необходимо предусмотреть для них и обратное поведение. Если содержимое поля изменилось и оно валидно, сообщение об ошибке должно быть удалено. Другими словами нам нужно, чтобы live region-элементы могли реагировать как на возникновение, так и исчезновение ошибок. Добиться этого позволяет атрибут aria-relevant
:
<div aria-live="assertive" aria-relevant="additions removals">
<!-- добавляем сообщение об ошибке -->
</div>
Если же мы хотим, чтобы при изменениях внутри элемента зачитывалось все его содержимое, используем атрибут aria-atomic
. Значение по умолчанию — true
, это значит, что при любом изменении синтезатор заново прочтет элемент целиком (а не только изменившийся фрагмент). Какое значение выбрать — вопрос каждого конкретного случая. Так, если сообщение об ошибке соотносится с определенным полем для валидации, использовать aria-atomic="true"
имеет смысл. Если же “живую область” составляет вся форма целиком, это будет уже излишним.
role="alert"
Альтернатива live region — атрибут role="alert"
, если его присвоить непосредственно сообщению об ошибке.
<div role="alert">
<!-- сообщение об ошибке-->
</div>
Атрибут задает элементу поведение, как если бы он содержал aria-live="assertive"
и aria-atomic="true"
.
Управление фокусом
Когда добавляем сообщение об ошибке
При выводе сообщения, с фокусом специально делать ничего не нужно. Если проверка осуществляется при переходе на следующее поле, то скорее всего фокус окажется на нем. С точки зрения пользователя, перехват фокуса и возвращение его на поле с ошибкой — непредвиденное поведение. Это — антипаттерн.
Перехват сабмита при наличии ошибок
В случае, если вы перехватываете отправку формы, хорошей идеей будет переводить фокус на элемент, содержащий список ошибок (поместить его можно, например, в начало формы). Еще лучше — сделать каждую из них ссылкой на соответствующее поле. Это значительно упростит их корректировку.
Обратите внимание, такой подход потенциально конфликтен c aria-live="assertive"
, так как live regions буду зачитаны синтезатором до списка ошибок. Поэтому имеет смысл выбрать только одну из указанных техник.
Язык
Выше мы говорили о способах улучшить работу с веб-формами для пользователей скринридеров. Другой ключевой фактор их оптимизации, уже для всех пользователей, — язык.
Вне зависимости от того, идет речь о сложной или простой форме, убедитесь, что пользователю легко понять ваши сообщения. Постарайтесь доступно описать ошибки и как их исправить. Это именно то, что действительно поможет заполнить форму без лишних хлопот.
Заключение
В статье я говорил о трех факторах доступности при создании сообщений об ошибках:
- указывайте на содержащие ошибки поля при помощи атрибута
aria-invalid
; - сообщайте о возникновении ошибки, добавляя их в live region-элементы, либо с помощью атрибута
role="alert"
для самого сообщения - убедитесь, что содержание ошибок и то, как их можно исправить, описано доступным и понятным языком
Моя благодарность Anneke и Matijs за редактуру и Krijn за комментарии и замечания.