guides
Quando i messaggi di errore escludono gli utenti
I messaggi di errore accessibili non si riducono ad aggiungere attributi ARIA. Ecco cosa serve davvero per progettare errori che funzionino per tutti.
Il momento in cui il modulo si rompe
Immagina la scena: un utente cieco compila un modulo di checkout, lo invia e dal suo screen reader non sente nulla di utile. Nessun annuncio. Nessuna spiegazione. La pagina ha segnalato visivamente cinque errori di convalida in rosso, ma l’utente non ne ha idea. Preme di nuovo invia. E di nuovo. Alla fine se ne va.
Non è uno scenario marginale. La gestione inaccessibile degli errori è una delle barriere più comuni che troviamo negli audit reali, ed è una di quelle che tendono a frustrare gli utenti nel momento peggiore possibile — quando stanno cercando di completare una transazione o di inviare qualcosa di importante.
La buona notizia è che risolverla è in gran parte questione di sapere che aspetto ha una soluzione “fatta bene”. I fallimenti sono quasi sempre gli stessi pochi pattern.
Perché i messaggi di errore sono difficili per gli utenti di tecnologie assistive
Gli utenti vedenti che usano il mouse tendono a notare subito gli errori di convalida — il bordo rosso, l’icona di avviso, il testo che compare sotto il campo. Ma gli utenti che si affidano a screen reader, navigazione da tastiera o controllo vocale vivono un’esperienza fondamentalmente diversa.
Quando un modulo viene inviato e compaiono degli errori:
- Gli utenti di screen reader potrebbero non sentire nulla, a meno che il focus non si sposti sull’errore o una live region non lo annunci
- Gli utenti che navigano da tastiera devono poter raggiungere ogni messaggio di errore dalla tastiera e capire a quale campo appartiene
- Gli utenti del controllo vocale devono poter indicare i campi tramite un’etichetta visibile e accurata — se l’etichetta è sbagliata o mancante, sono bloccati
Niente di tutto questo avviene automaticamente. Devi costruirlo tu.
I criteri WCAG che si applicano
Quattro criteri di successo delle WCAG 2.2 riguardano direttamente la gestione degli errori:
3.3.1 Identificazione di errori (Livello A) — Se un errore viene rilevato automaticamente, l’elemento in errore viene identificato e descritto all’utente tramite testo. Non puoi comunicare gli errori solo attraverso il colore.
3.3.2 Etichette o istruzioni (Livello A) — I campi che richiedono un formato specifico devono renderlo chiaro prima o durante l’inserimento, non solo dopo che l’invio è fallito.
3.3.3 Suggerimenti per gli errori (Livello AA) — Se un errore viene rilevato e sono noti suggerimenti per correggerlo, forniscili. “Data non valida” non basta. “Inserisci la data nel formato GG/MM/AAAA” sì.
3.3.4 Prevenzione degli errori (Livello AA) — Per gli invii con conseguenze rilevanti (transazioni finanziarie, accordi legali), dai agli utenti la possibilità di rivedere, correggere e confermare prima che l’azione diventi definitiva.
C’è anche il criterio 4.1.3 Messaggi di stato (Livello AA), che riguarda i messaggi inseriti dinamicamente che non ricevono il focus — questi devono essere annunciati dalle tecnologie assistive tramite role="status" o role="alert".
Cosa serve davvero a un messaggio di errore accessibile
Fare bene i messaggi di errore richiede attenzione a quattro livelli distinti:
1. Il collegamento programmatico
Ogni messaggio di errore deve essere collegato al suo campo tramite aria-describedby. Questo dice agli screen reader di annunciare il testo dell’errore quando il campo riceve il focus.
<!-- Before: error text exists visually but is invisible to screen readers -->
<label for="email">Email</label>
<input type="email" id="email" class="error">
<p class="error-text">Enter a valid email address.</p>
<!-- After: programmatic association via aria-describedby -->
<label for="email">Email address</label>
<input
type="email"
id="email"
aria-describedby="email-err"
aria-invalid="true"
>
<p id="email-err" class="error-text">Enter a valid email address.</p>
L’attributo aria-invalid="true" segnala che il campo è attualmente non valido, cosa che la maggior parte degli screen reader annuncia quando il focus vi si posa.
2. La gestione del focus dopo l’invio
Quando un modulo viene inviato e sono presenti errori, il focus deve spostarsi in un punto utile. I due pattern più comuni:
- Spostare il focus su un riepilogo degli errori in cima al modulo, che elenca tutti gli errori con link ai campi corrispondenti
- Spostare il focus sul primo campo in errore
Se il focus resta sul pulsante di invio o non va da nessuna parte, gli utenti di screen reader devono scoprire gli errori da soli navigando il modulo — ammesso che sappiano che esistono.
// After validation fails, move focus to the error summary
const summary = document.getElementById('error-summary');
summary.setAttribute('tabindex', '-1');
summary.focus();
3. Annunci tramite live region per gli errori dinamici
Per gli errori che compaiono mentre l’utente digita (convalida inline in tempo reale), usa le live region ARIA, in modo che il messaggio venga annunciato senza che il focus debba spostarsi.
<p role="alert" aria-live="assertive" id="password-err">
Password must be at least 8 characters.
</p>
Usa role="alert" / aria-live="assertive" per gli errori che richiedono attenzione immediata. Usa role="status" / aria-live="polite" per i feedback meno urgenti che possono aspettare una pausa dell’utente.
4. Il messaggio di errore in sé
Il linguaggio conta. I messaggi di errore accessibili sono:
- Specifici: dicono cosa non va, non solo che qualcosa non va
- Azionabili: dicono all’utente esattamente cosa fare per correggere l’errore
- Cortesi: evitano formulazioni colpevolizzanti come “hai inserito un valore non valido”
| Inaccessibile | Accessibile |
|---|---|
| ”Input non valido" | "L’indirizzo email deve includere il simbolo @, es. nome@esempio.com" |
| "Errore" | "La data deve essere nel formato GG/MM/AAAA" |
| "Campo obbligatorio" | "Il nome completo è obbligatorio" |
| "Password non valida" | "La password deve avere almeno 8 caratteri e includere un numero” |
Pattern per i diversi scenari di errore
Errori inline sul campo
Il pattern più comune. Un messaggio di errore compare direttamente sotto il campo a cui si riferisce. Funziona bene per i moduli semplici. Richiede aria-describedby e aria-invalid per essere annunciato correttamente.
Banner di riepilogo degli errori
Per i moduli lunghi con più errori, inserisci in cima un riepilogo che elenca tutti i problemi come link che portano al campo corrispondente. Sposta qui il focus dopo un invio fallito. È il pattern usato da GOV.UK e ampiamente raccomandato per i moduli complessi.
Notifiche toast
I messaggi di breve durata che compaiono ai bordi dello schermo sono tra i pattern più inaccessibili in uso comune. Scompaiono prima che gli utenti di screen reader possano raggiungerli, spesso non vengono annunciati affatto e non offrono alcun percorso di recupero. Evita i toast per gli errori. Se proprio li usi, abbinali a uno stato di errore persistente sul modulo stesso.
Errori di sistema
Quando qualcosa va storto lato server, spiega all’utente in linguaggio semplice cosa è successo e cosa può fare. “Qualcosa è andato storto” senza ulteriori indicazioni lascia gli utenti in un vicolo cieco.
<div role="alert" aria-live="assertive">
<p>We couldn't save your changes due to a network error.
Please check your connection and try again.</p>
</div>
La checklist di test
Dopo aver implementato la gestione degli errori, verifica manualmente questi punti — gli strumenti automatici non ne rileveranno la maggior parte:
- L’invio di un modulo obbligatorio vuoto sposta il focus su un riepilogo degli errori o sul primo campo in errore
- Ogni messaggio di errore è collegato al suo campo tramite
aria-describedby - I campi in errore hanno
aria-invalid="true" - I messaggi di errore vengono annunciati quando il focus si posa sul campo interessato
- La convalida in tempo reale usa le live region
- I messaggi di errore usano un linguaggio specifico e azionabile — non solo “non valido”
- Il colore non è l’unico modo in cui gli errori vengono segnalati (icona o etichetta testuale insieme al rosso)
- L’errore è raggiungibile da tastiera con Tab
- L’ordine del focus dopo l’invio è logico e non salta in modo imprevedibile
- I messaggi toast sono abbinati a uno stato di errore persistente
Perché gli strumenti automatici si perdono quasi tutto
Uno scanner automatico può verificare se aria-describedby punta a un elemento esistente e se aria-invalid è presente. Non può verificare se il focus si sposta correttamente dopo l’invio, se il testo dell’errore è accurato o se una notifica toast svanisce prima di poter essere letta. I nostri audit di accessibilità manuali includono test specifici sui moduli con tecnologie assistive reali — l’unico modo affidabile per verificare che la gestione degli errori funzioni davvero da cima a fondo.
Se non sai a che punto sono i tuoi moduli, esegui una scansione gratuita per far emergere prima i problemi rilevabili automaticamente, e da lì prosegui.
Trova i problemi di accessibilità dei moduli prima dei tuoi utenti