Standarder · ARIA

Roll Sammansatt widget

menu

Markerar en behållare som en appmeny — popup-elementet för File/Redigera-menyer eller kontextmenyer. Det finns ingen HTML-motsvarighet. En webbplats navigeringslista är INTE en meny; använd <nav> med <ul> av länkar i stället.

När du ska använda

För en applikationsmeny — det popup-element som visas från en “Fil”-knapp eller en högerklicks-kontextmeny, med pilnavigering och Escape för att stänga. Barn måste vara role="menuitem", role="menuitemcheckbox", role="menuitemradio" eller role="separator".

Menyrollen har applikationssemantik. Det största enskilda misstaget på webben är att använda role="menu" för webbplatsnavigering, vilket fångar tangentbordsanvändare i pilnavigering, meddelar fel att länkarna är menyobjekt och bryter användarens mentala modell.

Tumregel: om utlösaren är en hyperlänk och posterna är hyperlänkar är det navigering, inte en meny. Använd <nav> och <ul>.

En meny MÅSTE ha ett tillgängligt namn — använd aria-label eller aria-labelledby som pekar på utlösaren.

Tangentbords- och fokuskontrakt

Enligt APG:s menymönster:

  • Utlösarknappen har aria-haspopup="menu" och aria-expanded. Att aktivera utlösaren öppnar menyn och flyttar fokus till det första menyobjektet.
  • Inuti menyn: upp/ned-pilar flyttar fokus mellan objekt; Home/End hoppar till första/sista.
  • Högerpil öppnar en undermeny (om det fokuserade objektet har en); vänsterpil återgår till föräldraменyn.
  • Enter eller Mellanslag aktiverar det fokuserade objektet och stänger menyn.
  • Escape stänger menyn och återger fokus till utlösaren.
  • Förtypning: att skriva en bokstav hoppar till nästa objekt som börjar med den bokstaven.

Enda tab-stop: bara ett menyobjekt i taget har tabindex="0"; resten har -1.

Vanliga fel

  • role="menu" på ett <nav>-element. Applikationssemantik åsidosätter navigationssemantik — skärmläsare slutar meddela det som ett navigeringslandmärke.
  • Meny utan ett parat aria-haspopup="menu" på utlösaren.
  • Escape stänger menyn men återger inte fokus till utlösaren, vilket lämnar användaren utan ankare.
  • Fokus flyttar INTE till det första menyobjektet när menyn öppnas — användarna måste tabba förbi ingenting.
  • Undermenyer som bara öppnas vid hovring, inte med tangentbord.

Exempel

<button id="actions" aria-haspopup="menu" aria-expanded="false" aria-controls="actionsMenu">
  Actions
</button>
<ul id="actionsMenu" role="menu" aria-labelledby="actions" hidden>
  <li role="menuitem" tabindex="0">Edit</li>
  <li role="menuitem" tabindex="-1">Duplicate</li>
  <li role="separator"></li>
  <li role="menuitem" tabindex="-1">Delete</li>
</ul>