Меню и подменю

Что делаем: превращаем меню в список ссылок и добавляем пункт «Ещё» с раскрывающимся подменю. Кнопка управляет подменю через aria-expanded и aria-controls, а небольшой скрипт переключает состояние.

Меню сайта — это nav со списком

Пункты меню — перечень ссылок, поэтому внутри nav лежит ul. Диктор скажет «навигация, список, 3 пункта». Без списка пункты просто идут подряд.

Подменю — это раскрывающийся блок

Ссылка ведёт на страницу, а кнопка — меняет состояние интерфейса, поэтому «Ещё» это button. Две вещи делают его понятным для программ:

  • aria-expanded — раскрыто подменю сейчас или нет (true или false);
  • aria-controls — какой элемент он раскрывает.

Скрытое подменю получает атрибут hidden, а скрипт снимает его и меняет aria-expanded одновременно. Состояние в атрибуте и состояние на экране не должны расходиться. Escape закрывает подменю и возвращает фокус на кнопку.

Чего здесь делать не нужно

<ul role="menu">
<li role="menuitem"><a href="/">Статьи</a></li>
</ul>

Роль menu относится к меню приложения, как в текстовом редакторе, со своим управлением стрелками. Для навигации по сайту её использовать нельзя: диктор переключится в режим, где обычные ссылки перестанут работать как ссылки.

По спецификации

  • aria-expanded: состояние раскрыто или свёрнуто у управляющего элемента.
  • aria-controls: указывает на элемент, которым управляет текущий.
  • Шаблон disclosure navigation: как строится навигация с раскрывающимися блоками.
  • Роль menu: меню приложения, а не навигации по сайту.
  • Атрибут hidden: скрывает элемент от всех, и от экрана, и от диктора.

Проверьте себя

Пункт «Ещё» раскрывает подменю. Что это?
Можно ли ставить role="menu" на меню сайта?

Редактор · index.html

Предпросмотр

Подготовка окружения…

Ожидание запуска Vite…
Терминал