Что такое меню в пользовательских интерфейсах? Набор горизонтальных ссылок в шапке сайта — меню. Вертикальный набор ссылок, переключающих экраны в мобильном приложении — меню. Список действий над файлом в верхней части приложения (например, File -> Save As...) — меню. Раскрывающийся при нажатии на иконку-бургер список категорий товаров в магазине — меню.
В спецификации ARIA есть роли
menu и menubar, а в спецификации WHATWG есть элемент <menu>. Есть большой соблазн использовать их не по назначению. Периодически я встречаю такое. Давайте разбираться.Согласно спецификации,
menu и menubar — это виджеты, которые предлагают список действий или функций, которые пользователь может вызвать. Эта роль уместна для меню, которые похожи на меню в десктопных приложениях. Что особенного в меню десктопных приложений? Дело в том, что в таких приложениях нет понятия "страница" и "URL-адрес". Пункты меню в десктопных приложениях выполняют какие-то действия, но не меняют URL.Вспомните любое десктопное приложение, например Photoshop, Figma, VSCode, Word, Paint. У всех них в верхней части есть горизонтальное меню — это
menubar. При нажатии пункта в этих меню происходит действие — открытие выпадающего вертикального меню — это и есть menu. Разница между menubar и menu в значении aria-orientation по умолчанию: horizontal для menubar и vertical для menu. Пользователи ожидают от menu и menubar возможности навигации между пунктами при помощи клавиш со стрелками, Home и End. От menu ожидается навигация стрелками вверх/вниз, а от menubar — влево/вправо.Согласно той же спецификации, внутри
menu и menubar могут располагаться только элементы с ролями menuitem, menuitemcheckbox и menuitemradio. Также элементы можно группировать при помощи роли group и разделять при помощи separator (в ARIA 1.3).А вот типичный блок с ссылками на сайте не является меню в контексте спецификации. Об этом пишут и в ARIA практиках. Набор ссылок на сайте — это навигация. Поэтому паттерн меню в таком случае не применим. Навигация — это про страницы, URL-адреса и фрагменты (якори). Меню — это про вызов действий в приложении. Это очень похоже на вопрос "кнопка или ссылка".
Так вот: если при нажатии на элемент происходит переход на другую страницу (или перерисовка с изменением URL в SPA), переход к разделу на странице (якорь), страницу можно открыть в новой вкладке, новом окне, в инкогнито, ссылку можно скопировать, сохранить в закладки, поделиться, ссылка должна индексироваться — это навигация. Для этого нужно использовать элементы с ролями
navigation и link, то есть встроенные элементы <nav> и <a>. Можно добавить список, если элементов больше 3-4.<nav aria-label="Main">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/pricing">Pricing</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
Если при нажатии на пункт открывается вложенное меню, диалоговое окно, меняется часть интерфейса приложения, происходит какое-то действие с данными, меняются настройки, режим работы и т.д. — это меню. Для этого нужно использовать паттерны
menu и menubar. Так как встроенных в HTML аналогов нет, то меню можно сконструировать из семантически-нейтральных элементов и соответствующих ролей. Часто его делают из списка. В этом есть смысл, но я предпочитаю использовать кнопки с ролями, так как они сами по себе интерактивные, в отличие от элементов списка.<div role="menu">
<button type="button" role="menuitem">Save...</button>
<button type="button" role="menuitem">Save As...</button>
<button type="button" role="menuitemcheckbox" aria-checked="false">Autosave</button>
<button type="button" role="menuitem">Open</button>
<button type="button" role="menuitem">Undo</button>
<button type="button" role="menuitem">Rendo</button>
</div>
Контекстные меню, открываемые щелчком правой кнопкой мыши по элементу или при помощи сочетания
Shift+F10 на Windows — это тоже меню. Но не используйте роли menu и menubar для навигации на сайте.