⌨️ Sviluppo web

ARIA: quando serve davvero e quando peggiora le cose

Ruoli, stati e proprietà ARIA con esempi: la prima regola di ARIA, aria-label, aria-expanded, regioni live e gli errori che rompono l'accessibilità.

ARIA (Accessible Rich Internet Applications) è un insieme di attributi che permette di descrivere alle tecnologie assistive ciò che l'HTML da solo non riesce a esprimere: che un elemento è una scheda di un pannello a schede, che un menu è aperto, che una parte della pagina si è aggiornata. È uno strumento potente, ma usato male fa più danni che benefici. La sua regola principale, infatti, è un invito a non usarlo.

La prima regola di ARIA

La specifica sull'uso di ARIA nell'HTML lo dice chiaramente: se puoi usare un elemento HTML nativo che ha già la semantica e il comportamento che ti servono, usa quello invece di aggiungere ARIA a un elemento generico.

<!-- Da evitare -->
<div role="button" tabindex="0" aria-pressed="false">Grassetto</div>

<!-- Meglio -->
<button type="button" aria-pressed="false">Grassetto</button>

Il motivo è che ARIA cambia solo ciò che viene annunciato, non il comportamento. Un div con role="button" viene annunciato come pulsante, ma non riceve il focus senza tabindex, non si attiva con Invio o Spazio senza codice aggiuntivo, non partecipa all'invio dei form. Stai promettendo all'utente un pulsante che non si comporta come tale.

Le tre famiglie di attributi

Ruoli

Descrivono che cos'è un elemento: role="dialog", role="tablist", role="tab", role="alert", role="switch". Molti ruoli corrispondono già a elementi HTML (button, navigation, main, list) e non vanno ripetuti: <nav role="navigation"> è ridondante.

Proprietà

Descrivono caratteristiche relativamente stabili: aria-label, aria-labelledby, aria-describedby, aria-controls, aria-required.

Stati

Descrivono condizioni che cambiano con l'interazione: aria-expanded, aria-pressed, aria-checked, aria-selected, aria-invalid, aria-disabled, aria-current. Vanno aggiornati via JavaScript ogni volta che lo stato reale cambia.

Dare un nome agli elementi

Ogni controllo interattivo ha bisogno di un nome accessibile: è ciò che il lettore di schermo pronuncia. Normalmente lo fornisce il testo visibile. Quando non c'è testo visibile, ARIA aiuta:

<button type="button" aria-label="Chiudi finestra">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>
  • aria-label assegna un nome tramite una stringa.
  • aria-labelledby usa il testo di un altro elemento, indicandone l'id; ha la precedenza su aria-label.
  • aria-describedby aggiunge una descrizione supplementare, letta dopo il nome.

Un consiglio pratico: se c'è un testo visibile, il nome accessibile dovrebbe contenerlo. Chi usa i comandi vocali dice "clicca Invia" leggendo ciò che vede; se il nome accessibile è diverso, il comando non funziona.

Un caso reale: il pulsante che apre un menu

Un menu a scomparsa è il classico punto in cui ARIA serve davvero, perché l'HTML non ha un modo nativo per dire "questo pulsante controlla quel pannello ed è aperto":

<button type="button" aria-expanded="false" aria-controls="menu-principale">
  Menu
</button>
<ul id="menu-principale" hidden>
  <li><a href="/servizi">Servizi</a></li>
  <li><a href="/contatti">Contatti</a></li>
</ul>
const btn = document.querySelector('[aria-controls="menu-principale"]');
const menu = document.getElementById('menu-principale');

btn.addEventListener('click', () => {
  const aperto = btn.getAttribute('aria-expanded') === 'true';
  btn.setAttribute('aria-expanded', String(!aperto));
  menu.hidden = aperto;
});

Lo stato aria-expanded permette al lettore di schermo di annunciare "Menu, pulsante, compresso" ed "espanso". L'attributo hidden nasconde il pannello a tutti, non solo visivamente.

Per pannelli espandibili semplici, prima di scrivere codice, valuta details e summary: offrono lo stesso comportamento in modo nativo.

Regioni live: annunciare gli aggiornamenti

Quando una parte della pagina cambia senza che l'utente vi abbia spostato il focus (un messaggio "Salvato", il numero di risultati di una ricerca, un errore dopo l'invio), chi usa un lettore di schermo non se ne accorge. Le regioni live risolvono:

<div aria-live="polite" id="stato"></div>
document.getElementById('stato').textContent = 'Modifiche salvate';
  • aria-live="polite" annuncia il cambiamento quando l'utente ha finito ciò che sta ascoltando.
  • aria-live="assertive" (o role="alert") interrompe subito: va riservato a messaggi urgenti.

La regione deve essere presente nella pagina prima che il contenuto cambi; inserire nel DOM un elemento già pieno spesso non produce alcun annuncio.

Nascondere con criterio

aria-hidden="true" rimuove un elemento dall'albero di accessibilità ma lo lascia visibile. È utile per icone decorative accanto a un testo. Non va mai messo su elementi che possono ricevere il focus, né su un contenitore che include controlli interattivi: l'utente da tastiera finirebbe su elementi "fantasma" che il lettore di schermo non annuncia.

Gli errori più comuni

  • Aggiungere ruoli ridondanti agli elementi nativi.
  • Usare role="button" o role="link" su div e span invece di elementi veri.
  • Dimenticare di aggiornare gli stati: un aria-expanded="false" fisso su un menu aperto è peggio di nessun attributo.
  • Usare aria-label su elementi non interattivi come div e span generici, dove spesso viene ignorato.
  • Costruire widget complessi (schede, caselle combinate, griglie) senza seguire i modelli di interazione da tastiera documentati nella guida alle pratiche di authoring ARIA del W3C.

In sintesi

  • La prima regola di ARIA è preferire sempre l'elemento HTML nativo.
  • ARIA cambia ciò che viene annunciato, non il comportamento: tastiera e focus restano a tuo carico.
  • Usa aria-label e aria-labelledby per dare un nome ai controlli senza testo visibile.
  • Aggiorna gli stati come aria-expanded a ogni cambiamento reale.
  • Le regioni live annunciano gli aggiornamenti; aria-hidden non va mai su elementi focalizzabili.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche