aria-live
Segna una regione i cui aggiornamenti devono essere annunciati dalla tecnologia assistiva senza spostare il focus. Per la maggior parte dei casi si sceglie «polite»; «assertive» è riservato agli aggiornamenti genuinamente urgenti. La regione deve essere presente nel DOM al momento del rendering iniziale.
Quando utilizzarlo
Quando una parte della pagina si aggiorna in modo asincrono e si desidera che gli utenti di screen reader ne siano informati senza interrompere la lettura in corso. I casi tipici sono: riepiloghi di validazione dei form, conteggi dei risultati di ricerca, notifiche toast, messaggi in una chat in streaming e contatori del carrello acquisti.
Il livello di cortesia va scelto con attenzione:
aria-live="polite"— attende che l’utente sia inattivo prima di annunciare. Da usare per quasi tutto: messaggi di stato, risultati caricati, elemento aggiunto al carrello.aria-live="assertive"— interrompe l’utente immediatamente. Riservato alle informazioni genuinamente urgenti — sessione in scadenza tra 30 secondi, invio del form fallito, pagamento rifiutato. L’abuso rende la pagina ostile.aria-live="off"(valore predefinito) — nessun annuncio.
I role nativi role="status" (implica polite) e role="alert" (implica assertive) includono aria-live con impostazioni predefinite appropriate. È preferibile usarli quando si adattano alla situazione; si ricorre a aria-live su un contenitore personalizzato solo quando non lo fanno.
Come mantenerla sincronizzata
La regola fondamentale: la live region deve essere presente nel DOM al rendering iniziale. I browser e le tecnologie assistive impostano la «sorveglianza» della regione quando essa appare per la prima volta nell’albero di accessibilità. Se si crea la regione e vi si inietta il contenuto nello stesso ciclo JavaScript, l’annuncio viene spesso perso.
Il pattern corretto è:
<div id="status" aria-live="polite"></div>
Il contenitore vuoto viene reso al caricamento della pagina. In seguito, il testo viene scritto al suo interno tramite JavaScript. Lo screen reader annuncia la modifica.
Ulteriori regole:
- L’aggiornamento avviene impostando
textContent; sostituire l’intero HTML esterno della regione può interrompere la sorveglianza. - Per ripetere gli annunci è necessaria una variazione del contenuto — scrivere due volte la stessa stringa spesso non produce un secondo annuncio. Si aggiunga un contatore, un timestamp o si svuoti brevemente la regione.
- Si abbini
aria-busy="true"durante aggiornamenti a più fasi per evitare annunci parziali. - Si abbini
aria-atomicper controllare se viene annunciata la differenza o l’intera regione.
Errori comuni
- Creare la live region nello stesso ciclo in cui si inserisce il contenuto — nessun annuncio.
- Usare
aria-live="assertive"per tutto. Gli utenti disattivano l’audio della scheda. - Impostare
aria-livesu un controllo dotato di focus. Le live region sono per gli aggiornamenti di stato, non per i widget interattivi. - Nascondere la live region con
display: none. Le regioni nascoste tramite CSS sono escluse anche dall’albero di accessibilità e non producono annunci; si utilizzi invece la tecnica visually-hidden (clip / sr-only). - Inserire contenuti molto lunghi (paragrafi di testo) in una live region tutto in una volta — l’utente non riesce a scorrere.
- Dimenticare di svuotare la regione dopo che il messaggio è stato letto, così i successivi aggiornamenti identici non producono nulla.
Esempio
<form>
<label for="zip">ZIP code</label>
<input id="zip" name="zip" />
<button type="submit">Look up</button>
</form>
<!-- Sempre presente dal rendering iniziale -->
<div id="lookup-status" aria-live="polite" class="sr-only"></div>
<script>
document.querySelector('form').addEventListener('submit', async (e) => {
e.preventDefault();
const status = document.getElementById('lookup-status');
status.textContent = 'Looking up location…';
const place = await lookup(document.getElementById('zip').value);
status.textContent = `Location: ${place}`;
});
</script>