Standardy · ARIA

Rola Widget

menuitem

Oznacza element jako wykonywalną pozycję wewnątrz menu lub paska menu. Nie ma odpowiednika w HTML — menu to konstrukcja wyłącznie ARIA. Stosuj tę rolę tylko podczas budowania rzeczywistego menu (w stylu aplikacji); zwykła lista nawigacyjna NIE powinna używać menu/menuitem.

Kiedy stosować

Wyłącznie wewnątrz role="menu" lub role="menubar", i tylko wtedy, gdy menu jest menu aplikacji — rodzajem naśladującym pasek Plik/Edycja/Widok aplikacji desktopowej, z jednym punktem tabulacji, nawigacją strzałkami i zamknięciem klawiszem Esc.

Nawigacja serwisu NIE jest menu. Używaj <nav> z <ul> zawierającym łącza <a>. Mylenie obu podejść to najczęstszy błąd ARIA w sieci — pułapkuje użytkowników klawiatury w nawigacji strzałkami tam, gdzie Tab byłby bardziej naturalny, i mówi czytnikom ekranu „menu aplikacji”, gdy treść to po prostu łącza.

Role siostrzane: menuitemcheckbox (dla pozycji menu z przełączaniem) i menuitemradio (dla wykluczających się wyborów wewnątrz menu).

Klawiatura i zarządzanie fokusem

Zgodnie z wzorcem menu APG:

  • Tab wchodzi do menu i wychodzi z niego — fokus ląduje na pierwszej pozycji menuitem przy wejściu. Tab NIE przechodzi przez poszczególne pozycje.
  • Strzałki Góra/Dół przenoszą fokus między pozycjami (z zawijaniem).
  • Strzałki Prawo/Lewo otwierają podmenu / wracają do nadrzędnego.
  • Enter lub Spacja aktywuje fokusowaną pozycję.
  • Escape zamyka menu i przywraca fokus na wyzwalaczu.
  • Wpisanie litery przenosi fokus na następną pozycję zaczynającą się od tej litery (typeahead).

Używaj ruchomego tabindex: tylko aktualnie fokusowana pozycja menuitem ma tabindex="0"; pozostałe mają tabindex="-1".

Częste błędy

  • Używanie role="menuitem" dla zwykłego łącza w nawigacji serwisu. Powoduje pułapki klawiaturowe i nieprawidłowe ogłoszenia czytnika ekranu.
  • Każda pozycja menuitem ma tabindex="0", przez co Tab przechodzi przez każdą z nich. Wzorzec wymaga jednego punktu tabulacji.
  • Podmenu otwierane po najechaniu kursorem, ale nie po naciśnięciu strzałki w prawo.
  • Escape zamyka podmenu, ale gubi fokus, pozostawiając użytkownika poza menu.
  • Pozycje bez dostępnych nazw, gdy jedyną treścią jest ikona — dodaj aria-label.

Przykład

<button id="fileBtn" aria-haspopup="menu" aria-expanded="false" aria-controls="fileMenu">
  Plik
</button>
<ul id="fileMenu" role="menu" aria-labelledby="fileBtn" hidden>
  <li role="menuitem" tabindex="0">Nowy</li>
  <li role="menuitem" tabindex="-1">Otwórz</li>
  <li role="menuitem" tabindex="-1" aria-haspopup="menu" aria-expanded="false">
    Otwórz ostatnie
  </li>
  <li role="separator"></li>
  <li role="menuitem" tabindex="-1">Zapisz</li>
</ul>