menu
Oznacza kontener jako menu aplikacji — wyskakujące menu w stylu Plik/Edycja lub menu kontekstowe. Nie ma odpowiednika w HTML. Lista nawigacyjna serwisu NIE jest menu; zamiast niej użyj <nav> z listą <ul> zawierającą łącza.
Kiedy stosować
Dla menu w stylu aplikacji — wyskakującego po kliknięciu przycisku „Plik” lub menu kontekstowego po kliknięciu prawym przyciskiem, z nawigacją strzałkami i zamknięciem klawiszem Escape. Elementy potomne muszą mieć rolę role="menuitem", role="menuitemcheckbox", role="menuitemradio" lub role="separator".
Rola menu niesie semantykę aplikacji. Największy błąd w sieci to używanie role="menu" dla nawigacji serwisu — pułapkuje to użytkowników klawiatury w nawigacji strzałkami, błędnie ogłasza łącza jako pozycje menu i niszczy model mentalny użytkownika.
Zasada praktyczna: jeśli wyzwalacz jest hiperłączem, a pozycje są hiperłączami, to jest to nawigacja, a nie menu. Użyj <nav> i <ul>.
Menu MUSI mieć dostępną nazwę — użyj aria-label lub aria-labelledby wskazującego na wyzwalacz.
Klawiatura i zarządzanie fokusem
Zgodnie z wzorcem menu APG:
- Przycisk wyzwalający ma
aria-haspopup="menu"iaria-expanded. Aktywowanie wyzwalacza otwiera menu i przenosi fokus na pierwszą pozycję menuitem. - Wewnątrz menu: strzałki Góra/Dół przenoszą fokus między pozycjami; Home/End skaczą do pierwszej/ostatniej.
- Strzałka w prawo otwiera podmenu (jeśli fokusowana pozycja je posiada); strzałka w lewo wraca do menu nadrzędnego.
- Enter lub Spacja aktywuje fokusowaną pozycję i zamyka menu.
- Escape zamyka menu i przywraca fokus na wyzwalaczu.
- Typeahead: wpisanie litery przenosi fokus na następną pozycję zaczynającą się od tej litery.
Jeden punkt tabulacji: tylko jedna pozycja menuitem ma jednocześnie tabindex="0"; pozostałe mają -1.
Częste błędy
role="menu"na elemencie<nav>. Semantyka aplikacji nadpisuje semantykę nawigacji — czytniki ekranu przestają ogłaszać element jako punkt orientacyjny nawigacji.- Menu bez skojarzonego
aria-haspopup="menu"na wyzwalaczu. - Escape zamyka menu, ale nie przywraca fokusu na wyzwalaczu, pozostawiając użytkownika bez orientacji.
- Fokus NIE jest przenoszony na pierwszą pozycję menuitem po otwarciu menu — użytkownicy muszą przez nic tabulować.
- Podmenu otwierane tylko po najechaniu kursorem, nie przez klawiaturę.
Przykład
<button id="actions" aria-haspopup="menu" aria-expanded="false" aria-controls="actionsMenu">
Akcje
</button>
<ul id="actionsMenu" role="menu" aria-labelledby="actions" hidden>
<li role="menuitem" tabindex="0">Edytuj</li>
<li role="menuitem" tabindex="-1">Duplikuj</li>
<li role="separator"></li>
<li role="menuitem" tabindex="-1">Usuń</li>
</ul>