Salta al contenuto principale

Accessibilità · ARIA & tastiera

ARIA & widget da tastiera

Linee guida applicate ai componenti interattivi del prodotto. Riferimenti canonici: MDN — Accessible web apps & widgets e MDN — Keyboard-navigable JavaScript widgets .

1. Semantica prima, ARIA poi

La regola d'oro ARIA: non usare ARIA se esiste un elemento HTML nativo con la stessa semantica. Un <button> nativo è sempre preferibile a un <div role="button">perché eredita gratis: focus, attivazione con Invio/Spazio, ruolo, stato disabilitato.

Usiamo ARIA solo per arricchire ciò che HTML non esprime: stati dinamici (aria-expanded,aria-pressed, aria-selected), relazioni (aria-controls,aria-labelledby, aria-describedby) e regioni live (aria-live).

2. tabindex — quando e come

  • tabindex="0": rende focalizzabile un elemento non focalizzabile di default e lo inserisce nell'ordine naturale del DOM.
  • tabindex="-1": focalizzabile solo via JavaScript (utile per spostare il focus, ad esempio su un dialog appena aperto o sul <main> dopo lo skip-link).
  • Mai usare tabindex positivo: rompe l'ordine di tab e crea barriere di navigazione.

3. Pattern di tasti per i widget composti

Per widget come tabs, menu, listbox, tree, combobox seguiamo i pattern di tastiera ARIA Authoring Practices:

  • Tabs: / spostano la selezione, Home/End ai bordi, Tab esce dal widget.
  • Menu / Listbox: / tra le voci, Esc chiude.
  • Dialog modale: focus intrappolato finché aperto, Esc chiude, focus restituito al trigger.
  • Toggle / Switch: Spazio commuta lo stato (aria-pressed o aria-checked).

Questi pattern sono implementati nei nostri componenti Dialog, Switch, Tabs,Popover (basati su Radix UI, conformi a WAI-ARIA APG).

4. Focus management

  • Indicatore di focus sempre visibile, contrasto ≥ 3:1 con lo sfondo (WCAG 2.4.13).
  • Focus mai nascosto sotto barre sticky o tooltip (WCAG 2.4.11).
  • Quando un'azione cambia contesto (apertura dialog, navigazione), spostiamo programmaticamente il focus al nuovo punto utile e lo restituiamo all'origine alla chiusura.

5. Stati e relazioni ARIA che usiamo

  • aria-current="page" sul link di nav attivo.
  • aria-pressed sui toggle (Audio on/off, Riduci animazioni).
  • aria-expanded + aria-controls per disclosure.
  • aria-live="polite" per messaggi non urgenti, aria-live="assertive" per errori bloccanti.
  • aria-describedby per collegare campi di form ai messaggi di errore.
  • role="status" per stato runtime del sandbox di codice (Play/Stop, errori).

6. Cosa evitiamo

  • Cliccabili senza ruolo (<div onClick>) — sostituiti da <button> o link.
  • ARIA ridondante: ad esempio role="button" su un <button> nativo.
  • Etichette solo visive (icone senza aria-label) o solo testuali nascoste sotto immagini.
  • Tasti di scelta rapida che entrano in conflitto con quelli degli screen reader (per questo gli shortcut globali sono opzionali e documentati).

← Torna alla dichiarazione di accessibilità