Клавиатура и диктор: имя, роль, состояние
Зачем:Человек с диктором не видит страницу, а слушает её дерево: у каждого элемента есть имя, роль и состояние. После урока вы понимаете, как браузер собирает это дерево, делаете кнопку меню, окно и навигацию, с которыми справляются клавиатура и диктор, и умеете за пять минут проверить свою страницу NVDA или VoiceOver.
30 минут
Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.
Дерево доступности — то, что браузер строит из разметки для диктора: у каждого элемента есть имя, роль и состояние. Нативные элементы дают их сами.
Страница, которую слушают
Человек, который не видит экран, не «слушает картинку». Он слушает дерево доступности: параллельное дерево, которое браузер строит из вашей разметки специально для вспомогательных программ. В нём у каждого элемента есть три вещи:
- имя (name): как он называется. У кнопки «Меню», у поля «Телефон», у картинки её альтернативный текст;
- роль (role): что это такое. Ссылка, кнопка, заголовок, поле, список, навигация;
- состояние (state): в каком он положении. Раскрыто, нажато, выбрано, текущая страница, ошибка.
Диктор (программа чтения с экрана) собирает из них фразу вроде «Меню, кнопка, свёрнуто». Значительная часть доступности интерфейса состоит в том, чтобы эта фраза была верной.
Откуда браузер берёт имя, роль и состояние? Роль и поведение он берёт из самого элемента: button это кнопка, a с href это ссылка, h2 это заголовок второго уровня. Имя собирается по порядку из нескольких мест: aria-labelledby, aria-label, затем содержимое или связанная подпись (label для поля, alt для картинки), и в самую последнюю очередь title. Состояние берётся из атрибутов (checked, disabled, aria-expanded, aria-current).
Вывод, который вы уже знаете из первого урока про ARIA: нативный элемент даёт все три сразу, а div не даёт ни одного. Поэтому чаще всего достаточно выбрать правильный элемент и дать ему имя.
Как слушают страницу
Диктором пользуются иначе, чем читают глазами. По опросу WebAIM (одиннадцатый, лето 2026 года; ответили около 1800 человек) на длинной странице чаще всего начинают с заголовков: так сказали около двух третей. Поэтому в режиме просмотра клавиши быстрой навигации перепрыгивают между однотипными элементами: H к следующему заголовку, D к следующей области, F к следующему полю формы, K к ссылке, B к кнопке. Диктор может показать и список всех заголовков, всех областей, всех ссылок.
Из этого следует то, что вы делаете руками:
- Заголовки выстроены по порядку, h1 один, и по ним можно понять страницу, как по оглавлению.
- Области (landmarks) отмечены тем, что вы знаете как смысловые элементы:
header,nav,main,aside,footer. Если навигаций две, у каждой своё имя вaria-label: «Разделы сайта», «Подвал». - Ссылки понятны вне контекста. «Подробнее» в списке из десяти ссылок звучит десять раз одинаково; пишите «Подробнее об услуге: межевание».
- Поля подписаны. Без подписи диктор скажет «поле ввода», и человек не знает, что вводить.
Диктор, кстати, разный: по тому же опросу на компьютере чаще всего используют JAWS (платная) и NVDA (бесплатная), в телефонах это VoiceOver у iPhone и TalkBack у Android. Слова у каждой программы немного различаются, а смысл тот же.
Проверьте себя: из чего диктор складывает «Меню, кнопка, свёрнуто»?
Имя «Меню» берётся из содержимого кнопки, роль «кнопка» от самого элемента button, состояние «свёрнуто» от атрибута aria-expanded=“false”.
Клавиатура: порядок, фокус и управление
Фокус и порядок вы знаете из первого прохода. Что нужно добавить для сложных элементов.
- Tab переходит между элементами, Shift+Tab назад. Внутри составных элементов (набор переключателей, вкладки, меню) между пунктами ходят стрелки, а Tab проходит всю группу целиком. Для самодельных виджетов это нужно программировать; руководство ARIA Authoring Practices Guide описывает ожидаемое поведение каждого.
- Enter нажимает ссылку и кнопку, Пробел нажимает кнопку и ставит флажок, Esc закрывает окно, всплывающее меню или подсказку.
- Раскрывающиеся блоки проще всего делать кнопкой с
aria-expandedиaria-controls: диктор объявит «свёрнуто» или «развёрнуто». Такой шаблон называют disclosure, и им стоит заменять самодельные «меню» с рольюmenu, которая обещает больше, чем сделано. - Окна. Модальное окно должно: переносить фокус внутрь, не выпускать Tab наружу, закрываться по Esc и возвращать фокус на кнопку, которая его открыла. Нативный элемент
dialogс методомshowModal()всё это делает сам; достаточно дать ему имя черезaria-labelledby.
Проверьте себя: что делает элемент dialog после showModal() для клавиатуры?
Переносит фокус внутрь, делает остальную страницу недоступной, закрывается по Esc и возвращает фокус на кнопку, открывшую окно.
Сообщения: что менялось на странице
Страница меняется без перезагрузки: появилась ошибка, добавился товар в корзину, прошла отправка. Зрячий это замечает, а диктор не знает, куда смотреть. Решение: живые области (live regions). Контейнер с role="status" (вежливо: прочитать, когда диктор освободится) или role="alert" (срочно, прерывая чтение) лежит в странице заранее, а потом в него вставляют текст. Диктор прочтёт вставленное сам, фокус не двигается.
Два правила. Контейнер должен существовать до вставки текста, иначе многие программы не объявят. И не объявляйте всё подряд: десять сообщений за секунду делают страницу невыносимой.
Скрытое: кто что видит
display: noneи атрибутhiddenубирают элемент и для глаз, и для диктора, и для клавиатуры. Так скрывают то, что действительно не нужно (закрытое меню).aria-hidden="true"убирает элемент только для диктора; фокус до него по-прежнему дойдёт. Им скрывают декоративное (иконку рядом с текстом), и никогда не ставят на то, что можно сфокусировать.- Класс «только для диктора» (текст сдвинут за край экрана, но остаётся в дереве) нужен для подписи иконке без слов. Часто проще атрибут
aria-label.
Схема ниже: три элемента, каждый написан несколькими способами. Смотрите, доходит ли до него Tab, работает ли Enter и что говорит диктор.
Выберите элемент и способ, которым он написан. Справа видно, что с ним делают клавиатура и диктор. Слова диктора условны: каждая программа говорит чуть иначе, но смысл тот же.
<div onclick="open()">Меню</div>
- Tab доходит
- ✕ нет
- Enter и Пробел работают
- ✕ нет
- Диктор говорит
- «Меню» (обычный текст, роль не названа)
- Вывод
- Мышью работает, клавиатурой и диктором нет: фокус сюда не доходит.
Текстовая альтернатива: схема показывает для кнопки меню, поля и окна, как разные способы разметки ведут себя с клавиатурой и с диктором. Нативные элементы (button, label с input, dialog) получают фокус, управляются клавишами и называются сами; div с обработчиком клика и ролью требует дописывать всё это вручную.
Проверка за пять минут
Включите диктор: NVDA для Windows бесплатен, в macOS VoiceOver включается сочетанием Command+F5. Затем:
- Закройте глаза или отвернитесь от монитора (или погасите экран).
- Клавишей H пройдите по заголовкам: складывается ли оглавление?
- Клавишей D пройдите по областям: есть ли навигация и основное?
- Дойдите до формы клавишей F. Услышали ли вы подпись каждого поля?
- Выполните главное действие из брифа (запись, заказ). Дошли? Услышали ли результат?
Не получилось что-то из пунктов, значит, это приоритет для исправления. Для первого раза не нужно знать все команды: достаточно этих пяти клавиш.
Практика
Вы остаётесь в эпохе 2014 года. На странице меню и окно сделаны из div, и работают они только мышью. Перепишите их нативными элементами и запишите в заметке, что скажет диктор. Скрипт внизу уже подключён: он ищет элементы по id и переключает aria-expanded.
Проверка смотрит на разметку: на области, имена, состояния и отсутствие самодельных кнопок. Услышать результат проверка не может: после урока включите диктор и пройдите страницу своим пятиминутным сценарием.
Что было не так раньше
В эпоху jQuery меню делали из div и span с обработчиками кликов, а окна из полупрозрачных слоёв, и всё это хорошо выглядело на картинке. Для диктора такие страницы были набором безымянных блоков, а клавиатурой по ним нельзя было пройти. Появился ARIA, чтобы описать то, чего нет в HTML. Сейчас большинство того, ради чего его придумали, появилось в самом HTML: button, dialog, details, search. Правило осталось прежним: сначала нативный элемент, и лишь потом ARIA.
Практика
Готовлю вашу страницу…
Тест
Вопрос 1 из 6
Карточки
Эти карточки попадут в повторение, когда вы завершите урок.
Что слышит человек с диктором?
Ответ
Не картинку, а дерево доступности: у каждого элемента имя, роль и состояние (например «Меню, кнопка, свёрнуто»). Браузер строит его из разметки.
Почему нативные элементы лучше самодельных?
Ответ
button, a, input, label и dialog уже получают фокус, управляются клавишами и сообщают роль. У div с onclick этого нет, и ARIA лишь меняет озвучивание, но не добавляет поведения.
Что должно делать модальное окно?
Ответ
Перенести фокус внутрь, не выпускать Tab наружу, закрываться по Esc, вернуть фокус на кнопку. Нативный dialog с showModal() делает это сам.
Как объявить сообщение, не двигая фокус?
Ответ
Контейнер с role="status" (вежливо) или role="alert" (срочно) заранее лежит в странице, а потом в него вставляют текст. Диктор прочтёт его сам.
Пятиминутная проверка диктором?
Ответ
Включить NVDA или VoiceOver. Пройти по заголовкам (клавиша H), областям (D), полям (F). Выполнить главное действие, не глядя в экран: слышно ли, что это и что произошло.
Источники
- ARIA Authoring Practices Guide (W3C WAI) только ссылка, по-английски
- APG: Modal Dialog pattern только ссылка, по-английски
- APG: Disclosure pattern только ссылка, по-английски
- <dialog> (MDN) CC BY-SA, по-английски
- ARIA live regions (MDN) CC BY-SA, по-английски
- Manual Screen Reader Testing (WebAIM) только ссылка, по-английски
- Screen Reader User Survey #11 (WebAIM, 2026) только ссылка, по-английски
Дальше
Теперь вы знаете: клавиатура и чтение с экрана: имя, роль, состояние.