Как сделать сообщения об ошибках доступными

Перевод “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 за комментарии и замечания.