Accessibilità

Che cos'è ARIA (e quando non va usato)

ARIA è una specifica W3C che aggiunge ruoli e stati all'HTML per le tecnologie assistive. Va usata solo se l'elemento nativo non basta: casi e limiti.

In sintesi

  • ARIA descrive ruoli, stati e proprietà per l'albero di accessibilità; non aggiunge comportamento.
  • La prima regola è non usarla quando un elemento HTML nativo fa già il lavoro.
  • Un ruolo sbagliato è peggio di nessun ruolo: rompe nome, focus e annuncio.

ARIA (Accessible Rich Internet Applications) è una specifica W3C che aggiunge ruoli, stati e proprietà all'HTML per le tecnologie assistive. Non aggiunge comportamento: se manca tastiera o focus, ARIA non li crea.

Cosa aggiunge davvero

Tre famiglie di attributi. role dichiara che tipo di controllo è un elemento; aria-* descrive stato e proprietà, per esempio aria-expanded o aria-invalid; le live region, come role="status", annunciano un cambiamento senza spostare il focus. La specifica vigente è WAI-ARIA 1.2, W3C Recommendation del 6 giugno 2023, pubblicata con W3C Document License.

La prima regola

La WAI-ARIA Authoring Practices apre con una regola semplice: se un elemento HTML nativo offre già semantica e comportamento, usa quello e non aggiungere un ruolo. Un <button> è cliccabile, riceve focus e risponde a Enter e Space; un <div role="button"> riceve il nome ma non il resto. La guida è pubblicata da W3C con W3C Document License; la semantica degli elementi è nello HTML Living Standard, WHATWG, licenza CC BY 4.0.

Tre casi in cui ARIA serve

  • Widget compositi: una tab o un combobox costruito da zero ha bisogno di ruoli, aria-selected e gestione delle frecce.
  • Stato dinamico: un pannello che si apre dichiara aria-expanded; un errore di form dichiara aria-invalid e un messaggio collegato.
  • Annuncio asincrono: un role="status" comunica «3 risultati» dopo una ricerca, senza rubare il focus.

Tre casi in cui rompe

Il primo è aria-hidden="true" su un contenitore che include un link o un bottone: il controllo resta raggiungibile da tastiera ma sparisce dall'albero di accessibilità. Il secondo è aria-label su un bottone che ha già un testo visibile: il nome accessibile cambia e non corrisponde più a ciò che l'utente vede e detta. Il terzo è un ruolo che promette un comportamento mai implementato, come role="tablist" senza navigazione con le frecce. In tutti e tre i casi il lettore di schermo annuncia qualcosa che il codice non mantiene.

Come verificarlo

Un test automatico trova gli errori statici, non il flusso. Pa11y è open source con licenza LGPL-3.0 e applica regole WCAG alla pagina renderizzata.

npx --yes pa11y https://example.com --standard WCAG2AA

Il comando restituisce una lista di violazioni con selettore e criterio. Poi fai il test che nessuno strumento sostituisce: tab attraverso la pagina, apri e chiudi il widget con Enter, Space ed Escape, e ascolta l'annuncio con VoiceOver o NVDA.

Il catalogo EneUI

EneUI indicizza i componenti della categoria accessibilità e i dialog. Un record verificato è dialog di Origin UI, licenza MIT dichiarata a monte: dipende da @radix-ui/react-dialog e non reinventa il focus trap. Controllo eseguito il 1 novembre 2026 sul catalogo da 111.985 componenti.

La limitazione

ARIA cambia l'albero di accessibilità, non il comportamento. Se il widget non gestisce focus, tastiera e ordine di tabulazione, nessun attributo lo salva; e un ruolo sbagliato può rendere il componente peggiore di un <div> senza attributi.

Dove continuare

La checklist operativa è in componenti React accessibili. L'errore più frequente, con causa e fix, è in aria-label sui bottoni; il confronto tra primitive headless è in Radix, Base UI e React Aria.

Domande frequenti

ARIA è obbligatorio?

No. ARIA serve solo quando un elemento HTML nativo non copre il ruolo o lo stato. Un bottone nativo non ha bisogno di role="button".

Posso usare aria-label su qualsiasi elemento?

No. aria-label dà un nome accessibile solo agli elementi che lo supportano e non deve contraddire il testo visibile. Su un bottone con testo, il nome visibile basta.

ARIA aggiunge il supporto da tastiera?

No. ARIA descrive ruoli, stati e proprietà, ma non gestisce eventi. Enter, Space, Escape e le frecce restano a carico del codice.

aria-hidden="true" nasconde un elemento anche a tastiera?

No, e questo è il problema. Un controllo focusabile dentro un contenitore aria-hidden resta raggiungibile ma non viene annunciato; va rimosso dal tab order o non nascosto.

Come verifico ARIA senza screen reader?

Con un test automatico trovi solo una parte. Pa11y o axe segnalano ruoli non validi e nomi mancanti; il flusso va provato da tastiera e con VoiceOver o NVDA.