Представьте интерфейс: сетка с карточками статей блога, над которой горизонтальный список тегов. Нажатие по тегу меняет текущий состав статей в сетке. Всё происходит на одной странице без перезагрузки.
Теги реализованы как радио-кнопки, потому что логика подразумевает один активный тег. Если бы активных тегов могло быть несколько, вместо радио-кнопок были бы флажки. Разметка для описанного интерфейса выглядела бы так:
<form>
<fieldset>
<legend>
Теги
</legend>
<label for="tag-1">
<input
type="radio"
name="tag"
value="tag-1"
>
Тег 1
</label>
<label for="tag-2">
<input
type="radio"
name="tag"
value="tag-2"
>
Тег 2
</label>
<!-- остальные теги -->
</fieldset>
</form>
<ul>
<!-- список статей -->
</ul>
Изменение списка происходит динамически при выборе тега с помощью JS. Это довольно распространённый подход. Возникает вопрос: доступен ли такой интерфейс и поведение? А именно изменение списка при выборе радио-кнопки тега.
Критерий 3.2.2 On Input гласит: изменение настроек любого компонента пользовательского интерфейса не должно автоматически приводить к изменению контекста, если пользователь заранее не предупреждён об этом.
Радио-кнопка по определению считается компонентом пользовательского интерфейса. Настройки — это различные свойства и состояния, которые меняются при взаимодействии. У радио-кнопки это состояние «отмечено»/«не отмечено».
Изменение контекста — это существенное изменение в пользовательском агенте (браузере), области просмотра, фокусе или содержимом страницы, которое меняет её смысл. Это может дезориентировать пользователей, если они этого не ожидают.
Не всегда изменение контента это изменение контекста. Но изменение списка статей так, что отображаются только статьи выбранного тега, достаточно сильно меняет смысл страницы и вполне может считаться изменением контекста.
Получается, что изменение состояния радио-кнопок приводит к изменению контента, при котором существенно меняется смысл страницы. Критерий 3.2.2 нарушен, а интерфейс исходя из этого можно считать недоступным.
Как это исправить? WCAG предлагает два способа:
- Добавить кнопку отправки формы;
- Добавить предупреждение перед компонентом.
Отправка формы — ожидаемое действие, которое изменяет контекст. Добавление кнопки отправки решает проблему. При этом не обязательно делать традиционную отправку с перезагрузкой страницы, по-прежнему можно менять список через JS.
Это надёжно и понятно для пользователей: выбор опции и подтверждение выбора. Есть преимущество не только для доступности. Случайный выбор не того тега не приведёт к выполнению JS-логики изменения списка статей и потенциальному сетевому запросу.
Но кнопка отправки — это дополнительный элемент и действие, которое пользователю нужно совершить. Это менее удобно с точки зрения UX. Убрать дополнительный шаг можно путём замены радио-кнопок на несколько кнопок отправки.
<fieldset>
<legend>
Теги
</legend>
<button
type="submit"
name="tag"
value="tag-1"
>
Тег 1
</button>
<button
type="submit"
name="tag"
value="tag-2"
>
Тег 2
</button>
<!-- остальные теги -->
</fieldset>
Второй вариант подразумевает добавление инструкции перед радио-кнопками. Она должна сообщать, что выбор тега приведёт к изменению списка статей. Причём текст должен быть видимым или скрытым, но доступным для визуального отображения.
<fieldset>
<legend>
Теги
</legend>
<p>
При выборе тега список статей
динамически изменяется.
</p>
<!-- теги -->
</fieldset>
Можно добавить переключатель, который активирует режим изменения списка статей при выборе радио-кнопки. Это одновременно будет работать как предупреждение и как способ отключить нежелательное поведение.
Всё это релевантно и для реализаций с группой кнопок-переключателей (с состоянием «нажата»/«не нажата») вместо радио-кнопок или флажков. Помимо фильтра тегов статей. проблема актуальна для товарных фильтров в интернет-магазинах.
#a11y