Доступне меню навігації
Оновлено 14 жовтня 2026 · 6 хв читання
Головна навігація — перше, чим користується кожен відвідувач, а в магазині вона часто розростається в мега-меню з категоріями, брендами та акціями. Найпоширеніша помилка доступності — не відсутній ARIA, а неправильний ARIA: role="menubar", скопійований з бібліотеки компонентів. Ця сторінка пояснює, що натомість радить APG. Вона входить до серії доступні UI-патерни.
Menu чи disclosure? Що каже APG
В APG є патерн Menu і Menubar для меню застосунків — «списку варіантів, таких як дії чи функції», що поводиться як меню в настільному програмному забезпеченні. Його приклад навігаційного menubar містить прямо виражене застереження:
«Патерн menubar вимагає складної функціональності, зайвої для типової навігації сайту» … «Патерн, більш придатний для типової навігації сайту з розкривними групами посилань, — це патерн Disclosure.»
APG додає, що патерн disclosure «краще підходить для більшості вебсайтів, бо мало хто потребує додаткової функціональності клавіатури». Його приклад disclosure navigation не використовує роль menu, бо вона «не забезпечує складної функціональності, якої очікують допоміжні технології». role="menu" — це обіцянка поведінки меню в стилі настільних програм; якщо сайт її не виконує, таким меню користуватися важче, ніж звичайними посиланнями.
Рекомендація: орієнтир nav, вкладені списки посилань і кнопки disclosure для груп.
Відповідні критерії WCAG
- 2.1.1 Клавіатура (A): кожне підменю відкривається з клавіатури, а не лише при наведенні.
- 1.3.1 Інформація та взаємозв'язки (A): списки й вкладеність передають ієрархію.
- 4.1.2 Назва, роль, значення (A): кнопки-перемикачі відкривають
aria-expanded. - 1.4.13 Вміст під час наведення курсора чи встановлення фокуса (AA): випадні панелі, що відкриваються при наведенні, можна закрити (Escape), і на них можна навести курсор.
- 2.4.1 Пропускання блоків (A): посилання для пропуску або орієнтири, щоб обминути довге меню.
- 2.4.3 Порядок переміщення фокуса (A) і 2.4.7 Видимий фокус (AA).
- 3.2.3 Узгоджена навігація (AA): однаковий порядок на кожній сторінці.
- 1.4.10 Прокрутка в кількох напрямках (AA) і 2.5.8 Розмір активних елементів (мінімальні вимоги) (AA) для мобільного меню.
Приклад коду
<nav aria-label="Головне меню">
<ul>
<li>
<button type="button" aria-expanded="false" aria-controls="nav-women">Жінкам</button>
<ul id="nav-women" hidden>
<li><a href="/uk/women/dresses">Сукні</a></li>
<li><a href="/uk/women/shoes" aria-current="page">Взуття</a></li>
</ul>
</li>
<li><a href="/uk/sale">Розпродаж</a></li>
</ul>
</nav>
<script>
document.querySelectorAll('nav button[aria-expanded]').forEach((button) => {
const list = document.getElementById(button.getAttribute('aria-controls'));
button.addEventListener('click', () => {
const open = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!open));
list.hidden = open;
});
});
</script>
Примітки:
- Якщо верхній пункт має бути ще й посиланням на сторінку категорії, в APG є варіант «Disclosure Navigation Menu with Top-Level Links»: посилання та окрема кнопка-перемикач стоять поруч. Не робіть один елемент одночасно посиланням і перемикачем.
- Додайте Escape: закрийте відкриту групу й поверніть фокус на її кнопку, як у прикладі APG.
- На мобільному кнопка-«гамбургер» — це той самий disclosure:
aria-expanded, назва на кшталт «Меню», а панель іде за нею в DOM.
Взаємодія з клавіатури
З прикладу disclosure navigation APG:
| Клавіша | Функція |
|---|---|
| Tab / Shift + Tab | Переміщує по кнопках і посиланнях верхнього рівня, а коли групу відкрито, — по її посиланнях |
| Enter або Space на кнопці | Відкриває чи закриває групу |
| Enter на посиланні | Переходить за посиланням |
| Escape | Закриває відкриту групу й повертає фокус на її кнопку |
| Стрілки, Home, End | Необов'язково: переміщують між кнопками й посиланнями; доповнюють Tab, а не замінюють його |
Справжній menubar натомість вимагав би стрілок для переходу між пунктами, Tab для виходу з усього menubar і швидкого пошуку за першою літерою — це і є «складна функціональність», про яку йдеться в APG.
Типові помилки в інтернет-магазинах
- Мега-меню, що відкриваються лише при наведенні миші; користувачі клавіатури проходять Tab по верхніх посиланнях і ніколи не дістаються підкатегорій.
role="menubar"іrole="menuitem"на звичайних посиланнях, часто з теми чи плагіна, без поведінки стрілок.- Приховані підменю, що досі можуть отримати фокус: Tab зникає в невидимих посиланнях (фокус губиться за
opacity: 0). - Назва категорії є і посиланням, і перемикачем, тож користувачі сенсорних екранів і клавіатури не можуть відкрити підменю.
- Немає
aria-expandedабо він ніколи не змінюється зfalse. - Кілька орієнтирів
navбез підписів (головний, футер, обліковий запис), тож користувачі програм зчитування з екрана не можуть їх розрізнити. - Кнопки-«гамбургери» без назви та мобільні меню, які не утримують і не повертають фокус, коли побудовані як накладка на весь екран.
Що знаходить автоматична перевірка, а що — ручне тестування
| Автоматично (правило axe-core) | Що знаходить |
|---|---|
link-name, button-name |
Посилання меню та кнопки-перемикачі чи «гамбургери» без назви |
aria-required-children, aria-required-parent |
menu/menubar без дочірніх menuitem, menuitem поза меню |
aria-allowed-role |
Ролі, що не підходять елементові (порада) |
aria-hidden-focus |
Посилання всередині підменю з aria-hidden, які досі можуть отримати фокус |
list, listitem |
Зламана структура списку в навігації |
landmark-unique |
Кілька навігаційних орієнтирів з однаковою назвою або без неї (порада) |
bypass, skip-link |
Немає способу пропустити меню; посилання для пропуску зі зламаною ціллю |
target-size |
Цілі меню, що надто малі |
Усі вони є картками в нашій бібліотеці правил. Сканування бачить сторінку такою, якою вона завантажується, із закритими підменю. Ручне тестування: відкрийте кожну групу клавішами Enter чи Space, перевірте, що aria-expanded змінюється, натисніть Escape, пройдіть клавішею Tab відкритою групою, перевірте, що закриті групи не можуть отримати фокус, і повторіть з мобільним меню на ширині 320 CSS-пікселів. Розширення для браузера може перевірити сторінку з відкритою групою.
Запустіть безкоштовну перевірку однієї сторінки на головній. Це автоматична перевірка, а не повний аудит.
Часті запитання
Чи варто в навігації сайту використовувати role="menu" або role="menubar"?
Зазвичай ні. APG попереджає, що патерн menubar вимагає складної функціональності, зайвої для типової навігації сайту, і радить патерн disclosure для навігації з розкривними групами посилань.
Що таке disclosure navigation?
Елемент nav зі списком посилань, де кожна група з підпосиланнями має кнопку з aria-expanded, що показує чи приховує вкладений список. Користувачі переходять ним клавішами Tab, Enter і Space, як і рештою сторінки.
Як позначити поточну сторінку в меню?
Поставте aria-current="page" на посиланні на сторінку, де перебуває користувач, і покажіть це ще й візуально, а не лише кольором.
Чи має меню підтримувати клавіші-стрілки?
У патерні disclosure — ні. Приклад APG підтримує стрілки, Home та End як необов'язкове доповнення до Tab. Справжній menubar, навпаки, мусить реалізовувати повну модель керування стрілками.
Чи може автоматична перевірка протестувати меню навігації?
Вона знаходить посилання й кнопки без назв, ролі меню без пунктів меню, дубльовані непідписані навігаційні орієнтири та приховані, але доступні для фокуса посилання. Вона не може перевірити, чи підменю відкриваються з клавіатури і чи оновлюється aria-expanded.
Джерела
- W3C WAI, APG Navigation Menubar example (caution about site navigation): https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/
- W3C WAI, APG Menu and Menubar pattern: https://www.w3.org/WAI/ARIA/apg/patterns/menubar/
- W3C WAI, APG Disclosure pattern: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/
- W3C WAI, APG Disclosure Navigation Menu example: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/
- W3C WAI, APG Menu Button pattern: https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/