Normen · ARIA

Rol Samengestelde widget

menu

Markeert een container als een toepassingsmenu — de popup van Bestand/Bewerken-stijlmenu's of contextmenu's. Er is geen HTML-equivalent. Een sitenavigatielijst is GEEN menu; gebruik daarvoor <nav> met <ul> van links.

Wanneer te gebruiken

Voor een toepassingsstijlmenu — de popup die verschijnt vanuit een knop “Bestand” of een rechtsklikmenu, met navigatie via pijltoetsen en sluiten via Escape. Kinderen moeten role="menuitem", role="menuitemcheckbox", role="menuitemradio" of role="separator" zijn.

De menu-rol heeft toepassingssemantiek. De grootste individuele fout op het web is het gebruik van role="menu" voor sitenavigatie, waardoor toetsenbordgebruikers gevangen zitten in pijltoetsnavigatie, links ten onrechte als menu-items worden aangekondigd en het mentale model van de gebruiker wordt verbroken.

Vuistregel: als de trigger een hyperlink is en de items hyperlinks zijn, is het navigatie, geen menu. Gebruik <nav> en <ul>.

Een menu MOET een toegankelijke naam hebben — gebruik aria-label of aria-labelledby dat verwijst naar de trigger.

Toetsenbord- en focuscontract

Volgens het APG menu-patroon:

  • De triggerknop heeft aria-haspopup="menu" en aria-expanded. Het activeren van de trigger opent het menu en verplaatst de focus naar het eerste menuitem.
  • Binnen het menu: pijl omhoog/omlaag verplaatst de focus tussen items; Home/End springt naar het eerste/laatste item.
  • Pijl rechts opent een submenu (als het gefocuste item er een heeft); pijl links keert terug naar het bovenliggende menu.
  • Enter of Spatie activeert het gefocuste item en sluit het menu.
  • Escape sluit het menu en retourneert de focus naar de trigger.
  • Typeahead: het typen van een letter springt naar het volgende item dat met die letter begint.

Eén tabstop: slechts één menuitem heeft tegelijk tabindex="0"; de rest heeft -1.

Veelvoorkomende fouten

  • role="menu" op een <nav>-element. Toepassingssemantiek overschrijft navigatiesemantiek — schermlezers kondigen het niet meer aan als navigatielandmark.
  • Menu zonder gekoppeld aria-haspopup="menu" op de trigger.
  • Escape sluit het menu maar retourneert de focus niet naar de trigger, waardoor de gebruiker vastloopt.
  • De focus verplaatst zich NIET naar het eerste menuitem wanneer het menu opent — gebruikers moeten door niets heen tabben.
  • Submenu’s die alleen bij hover openen, niet bij toetsenbord.

Voorbeeld

<button id="actions" aria-haspopup="menu" aria-expanded="false" aria-controls="actionsMenu">
  Acties
</button>
<ul id="actionsMenu" role="menu" aria-labelledby="actions" hidden>
  <li role="menuitem" tabindex="0">Bewerken</li>
  <li role="menuitem" tabindex="-1">Dupliceren</li>
  <li role="separator"></li>
  <li role="menuitem" tabindex="-1">Verwijderen</li>
</ul>