menu
Contrassegna un contenitore come menu applicativo — il popup dei menu in stile File/Modifica o i menu contestuali. Non esiste un equivalente HTML. La lista di navigazione di un sito NON è un menu; si utilizzi <nav> con <ul> di link.
Quando usarlo
Per un menu in stile applicativo — il popup che compare da un pulsante «File» o da un menu contestuale al clic destro, con navigazione tramite tasti freccia e chiusura con Escape. I figli devono avere role="menuitem", role="menuitemcheckbox", role="menuitemradio" o role="separator".
Il ruolo menu è una semantica da applicazione. L’errore più diffuso sul web è usare role="menu" per la navigazione del sito, il che intrappola gli utenti da tastiera nella navigazione con i tasti freccia, annuncia i link come voci di menu e rompe il modello mentale dell’utente.
Regola empirica: se il trigger è un collegamento ipertestuale e le voci sono collegamenti ipertestuali, si tratta di navigazione, non di un menu. Si utilizzi <nav> e <ul>.
Un menu DEVE avere un nome accessibile — si usi aria-label o aria-labelledby che punta al trigger.
Contratto tastiera + focus
Secondo il pattern menu APG:
- Il pulsante trigger ha
aria-haspopup="menu"earia-expanded. L’attivazione del trigger apre il menu e sposta il focus sul primo menuitem. - All’interno del menu: i tasti freccia Su/Giù spostano il focus tra le voci; Home/Fine saltano alla prima/ultima.
- Il tasto freccia Destra apre un sottomenu (se la voce attiva ne ha uno); il tasto freccia Sinistra torna al menu padre.
- Invio o Spazio attivano la voce attiva e chiudono il menu.
- Escape chiude il menu e restituisce il focus al trigger.
- Typeahead: digitare una lettera salta alla voce successiva che inizia con quella lettera.
Singolo tab-stop: solo un menuitem alla volta ha tabindex="0"; gli altri hanno -1.
Errori comuni
role="menu"su un elemento<nav>. La semantica applicativa sovrascrive quella di navigazione — gli screen reader smettono di annunciarlo come landmark di navigazione.- Menu senza il corrispondente
aria-haspopup="menu"sul trigger. - Escape chiude il menu ma non restituisce il focus al trigger, lasciando l’utente senza orientamento.
- Il focus NON si sposta al primo menuitem all’apertura del menu — gli utenti devono premere Tab nel vuoto.
- Sottomenu che si aprono solo al passaggio del mouse, non da tastiera.
Esempio
<button id="actions" aria-haspopup="menu" aria-expanded="false" aria-controls="actionsMenu">
Azioni
</button>
<ul id="actionsMenu" role="menu" aria-labelledby="actions" hidden>
<li role="menuitem" tabindex="0">Modifica</li>
<li role="menuitem" tabindex="-1">Duplica</li>
<li role="separator"></li>
<li role="menuitem" tabindex="-1">Elimina</li>
</ul>