Вопрос #1614920

Проектирование UI: какие практики и ARIA-атрибуты вы используете, чтобы форма была доступна для экранных читалок и клавиатурной навигации; приведите пример конкретных элементов

Ответы
1


Кратко — лучшие практики и конкретные ARIA-атрибуты + примеры элементов.
Основные практики
- Использовать семантическую HTML-разметку (label, fieldset/legend, button, nav, main, header, footer, input/select/textarea). ARIA не заменяет семантику, а дополняет.
- Обеспечить связанность метки и поля: prefer `` или вложенный label.
- Связывать подсказки/ошибки через `aria-describedby`.
- Явно обозначать требуемые поля и валидность: `aria-required`, `aria-invalid`.
- Управлять фокусом (логичный tab-order, видимый фокус, focus trap в модалках, возврат фокуса).
- Делать все кастомные контролы доступными: присваивать role, реализовать keyboard handlers (Enter/Space/стрелки/Escape) и поддерживать атрибуты состояния (`aria-checked`, `aria-selected`, `aria-expanded` и т. п.).
- Минимизировать использование `aria-*`, если есть нативный элемент с нужной семантикой.
- Тестировать клавиатурой и экранными читалками (NVDA, VoiceOver, TalkBack) и автоматическими инструментами (axe, Lighthouse).
Полезные ARIA-атрибуты и их назначение
- `aria-label` — явное имя для элемента, если нет видимой метки.
- `aria-labelledby="id"` — имя, сформированное из другого DOM-элемента (лучше, чем aria-label если есть видимая метка).
- `aria-describedby="id"` — ссылка на подсказку/описание/сообщение об ошибке.
- `aria-required="true"` — поле обязательно.
- `aria-invalid="true"` — поле содержит ошибку (вместе с явным сообщением).
- `role="alert"` / `aria-live="polite|assertive"` — для объявлений ошибок/информации динамически.
- `role="dialog"` + `aria-modal="true"` — модальные окна; вместе с управлением фокусом.
- `aria-expanded="true|false"` и `aria-controls="id"` — раскрываемые панели/меню.
- `aria-checked`, `aria-pressed`, `aria-selected` — для кастомных чекбоксов/переключателей/вкладок.
- `tabindex="0"` (делает фокусируемым) и `tabindex="-1"` (позволяет фокусировать программно).
- `aria-hidden="true"` — скрыть от AT (использовать осторожно).
- `aria-activedescendant` — для управляемых списков/комплектов с управлением фокусом.
Конкретные примеры
1) Текстовое поле с меткой и сообщением об ошибке
```html
Email<input id="email" name="email" type="email"
aria-describedby="email-help email-error"
aria-required="true"
aria-invalid="true">Мы отправим подтверждениеВведите корректный email ```
Пояснения: `aria-describedby` связывает подсказку и ошибку; `role="alert"` объявит ошибку сразу.
2) Кастомный чекбокс (доступный)
```html
<div id="agree" role="checkbox" tabindex="0"
aria-checked="false" aria-labelledby="agree-label">Я принимаю условия ```
Требуется JS: пробел/Enter переключают `aria-checked`, обновляют визуал и синхронизируют с состоянием формы (или использовать скрытый native input).
3) Модальное окно
```html
<div id="dialog" role="dialog" aria-modal="true"
aria-labelledby="dlg-title" aria-describedby="dlg-desc">Подтвердите действие

Это действие нельзя отменить.

ПодтвердитьОтмена ```
Пояснения: при открытии — сохранить предыдущий фокус, установить фокус на первый интерактивный элемент, трапить таб внутри диалога, при закрытии — вернуть фокус.
4) Вкладки (tabs)
```html
Вкладка 1Вкладка 2Содержимое 1Содержимое 2 ```
Пояснения: стрелки клавиатуры переключают `aria-selected` и фокус; неактивные панели можно скрывать через `hidden` или `aria-hidden="true"`.
5) Комбобокс / автокомплит
```html
<input id="search" role="combobox" aria-autocomplete="list"
aria-expanded="false" aria-controls="listbox" aria-haspopup="listbox">Option 1 ...
```
Пояснения: при навигации стрелками обновлять `aria-activedescendant` на input; при открытии ставить `aria-expanded="true"`.
Короткие рекомендации по тестированию
- Проверьте клавиатурную навигацию (Tab, Shift+Tab, Enter, Space, стрелки, Escape).
- Проверяйте на реальных читалках (NVDA/VoiceOver/TalkBack).
- Автоматические сканеры (axe, Lighthouse) для быстрых ошибок, но не вместо ручного теста.
Если нужно — могу прислать минимальные JS-фрагменты для управления фокусом и состояниями для любого из примеров.

Минимум 10 символов
Прямой эфир