Normative · ARIA

Ruolo Widget

tab

Contrassegna un elemento come una scheda in un'interfaccia a schede. Un tab DEVE trovarsi all'interno di un tablist e DOVREBBE riferirsi al proprio tabpanel associato tramite aria-controls. Non esiste un elemento HTML nativo per le schede — il pattern tab è esclusivamente ARIA.

Quando utilizzarlo

Per una singola scheda all’interno di una barra di schede disposta orizzontalmente o verticalmente. Un tab DEVE essere un figlio diretto di un elemento role="tablist" (o associato tramite aria-owns). Ogni tab DEVE puntare al proprio pannello con aria-controls="<tabpanel-id>". Il reciproco aria-labelledby si trova sul pannello e punta di rimando alla scheda.

Le schede sono un pattern da applicazione. Se le «schede» in questione sono in realtà link di navigazione verso pagine separate, è preferibile usare <nav> con link <a> — il cambio di URL rende inappropriato il pattern tab.

La scheda stessa è solitamente un <button>. La semantica del pulsante si combina correttamente con role="tab", e la gestione del focus e dell’attivazione è garantita automaticamente.

Contratto tastiera + focus

Secondo il pattern APG per le schede:

  • Il tasto Tab sposta il focus nel tablist, sulla scheda attiva. Un ulteriore Tab sposta il focus all’elemento successivo (tipicamente nel tabpanel stesso, se ha tabindex="0").
  • I tasti freccia sinistra/destra (o su/giù per i tablist verticali) spostano il focus tra le schede.
  • Home / Fine saltano alla prima / ultima scheda.
  • L’attivazione può essere automatica (focus = selezione) o manuale (Spazio/Invio per selezionare). Si consiglia la modalità manuale quando l’attivazione di una scheda innesca operazioni onerose.

Si utilizza un roving tabindex: solo la scheda selezionata ha tabindex="0".

Errori comuni

  • Tutti i tab con tabindex="0" — il tasto Tab scorre tutte le schede invece di spostarsi nel pannello.
  • Mancanza di aria-controls che colleghi il tab al tabpanel.
  • aria-selected="true" su più di un tab contemporaneamente.
  • Schede implementate con <a href="#section"> — il frammento URL cambia, il pulsante indietro naviga tra le schede e il pattern si interrompe.
  • Nessuna gestione del focus all’attivazione: cliccando su una scheda si aggiorna il pannello, ma la successiva pressione del tasto Tab riporta all’intestazione della pagina invece che al pannello.

Esempio

<div role="tablist" aria-label="Account settings">
  <button role="tab" id="t-profile"  aria-selected="true"  aria-controls="p-profile"  tabindex="0">Profile</button>
  <button role="tab" id="t-billing"  aria-selected="false" aria-controls="p-billing"  tabindex="-1">Billing</button>
  <button role="tab" id="t-security" aria-selected="false" aria-controls="p-security" tabindex="-1">Security</button>
</div>
<section role="tabpanel" id="p-profile"  aria-labelledby="t-profile"  tabindex="0">…</section>
<section role="tabpanel" id="p-billing"  aria-labelledby="t-billing"  hidden>…</section>
<section role="tabpanel" id="p-security" aria-labelledby="t-security" hidden>…</section>