Definizione — tabindex
è un attributo globale che determina se un elemento può ricevere il focus e in quale posizione della sequenza di tabulazione entrerà. È fondamentale per l’operabilità da tastiera e si collega a WCAG 2.1: 2.1.1 Tastiera (A), 2.4.3 Ordine di focus (A), 2.4.7 Focus visibile (AA), 4.1.2 Nome/Ruolo/Stato (A).
Valori e significato
tabindex="0"
— rende l’elemento focalizzabile entrando nell’ordine di tabulazione naturale (in base al DOM). Utile per rendere raggiungibili componenti non nativi quando necessario.
tabindex="-1"
— l’elemento è focalizzabile via script (es. element.focus()
) ma viene saltato dal tasto Tab. Serve per portare il focus su titoli, <main>
(skip link), contenitori o pannelli appena aperti.
tabindex=">0"
— impone un ordine personalizzato. È quasi sempre sconsigliato perché crea percorsi imprevedibili e fragili; preferisci riordinare il DOM o i CSS.
Buone pratiche
- Ordine DOM = ordine di focus: progetta l’HTML nella sequenza di lettura desiderata; evita di “correggere” l’ordine con
tabindex
positivo.
- Usa elementi nativi (
<button>
, <a>
, <input>
): sono già tastierabili senza tabindex
aggiuntivi.
- Skip link: aggiungi
tabindex="-1"
al target per consentire lo spostamento del focus:
<main id="contenuto" tabindex="-1">…</main>
- Roving tabindex (componenti complessi): un solo elemento per volta con
tabindex="0"
, gli altri -1
(es. tablist, menù, slider). Gestisci frecce/Home/End via JS.
- Focus solo su elementi utili: rendi focalizzabili solo i controlli interattivi o container che devono ricevere il focus per ragioni di accessibilità (es. titoli di dialog).
Esempi
Tablist con roving tabindex (principio)
<div role="tablist">
<button role="tab" id="t1" aria-selected="true" tabindex="0" aria-controls="p1">Profilo</button>
<button role="tab" id="t2" aria-selected="false" tabindex="-1" aria-controls="p2">Impostazioni</button>
</div>
<section id="p1" role="tabpanel" aria-labelledby="t1">…</section>
<section id="p2" role="tabpanel" aria-labelledby="t2" hidden>…</section>
Skip link → main
<a class="skip-link" class="text-primary" href="#contenuto">Salta al contenuto</a>
<main id="contenuto" tabindex="-1">
<h1>Titolo pagina</h1>
</main>
Div “finto bottone” (sconsigliato, solo se indispensabile)
<div role="button" tabindex="0" aria-pressed="false">Apri menu</div>
<script>
const btn = document.querySelector('[role=button]');
btn.addEventListener('keydown', e => {
if (e.key === 'Enter' || e.key === ' ') { /* azione */ e.preventDefault(); }
});
</script>
Errori comuni
- Usare
tabindex
positivo per forzare l’ordine: rompe WCAG 2.4.3 e confonde gli utenti.
- Rendere focalizzabili elementi non interattivi (card, paragrafi) senza motivo → rumore di tabulazione.
- Affidarsi a
tabindex
per “riparare” layout con ordine DOM errato.
- Mettere
aria-hidden="true"
su elementi focusabili: diventano invisibili allo screen reader ma raggiungibili da tastiera (incoerenza).
Test rapidi
- Naviga con Tab/Shift+Tab: la sequenza è logica e segue il contenuto?
- Apri un dialog: il focus entra nel titolo/contenuto e torna al trigger alla chiusura?
- Con strumenti dev, cerca
tabindex
positivi: puoi eliminarli ristrutturando DOM o usando roving tabindex?
Voci correlate e collegamenti utili
Naviga il Glossario dell'accessibilità A-Z
Richiedi una consulenza gratuita
Il nostro team di Web Accessibility Expert certificati UNI 11621-3 è pronto a guidarti con le migliori soluzioni per il tuo business!
Contattaci adesso