Criteri di successo WCAG · Level A

WCAG 3.3.1: Identificazione degli errori

WCAG 3.3.1 richiede che, quando un errore di input viene rilevato automaticamente, l’elemento in errore sia identificato e l’errore venga descritto all’utente in forma testuale. Questo garantisce che le persone con disabilità possano riconoscere, comprendere e correggere gli errori quando compilano i moduli.

Cosa Significa Questa Regola

WCAG 3.3.1 Error Identification è un criterio di successo di Livello A sotto il principio Comprensibile. Stabilisce: «Se un errore di input viene rilevato automaticamente, l’elemento che contiene l’errore è identificato e l’errore è descritto all’utente in forma testuale.» In termini pratici, ogni volta che il tuo sito web o la tua applicazione convalida automaticamente l’input dell’utente — al momento dell’invio del form, all’uscita dal campo (blur) o in tempo reale — devono avvenire due cose se viene rilevato un errore: il campo o controllo specifico che contiene l’errore deve essere chiaramente identificato e la natura dell’errore deve essere comunicata usando contenuto testuale effettivo (non solo colore, icona o suono).

Il criterio si applica a qualsiasi situazione in cui vengono raccolti input dagli utenti e la validazione avviene automaticamente. Questo include elementi di form HTML come <input>, <select>, <textarea>, così come widget interattivi personalizzati costruiti con ARIA. Copre la validazione lato client attivata da JavaScript, la validazione nativa del browser basata su attributi come required, pattern, minlength e type, così come i risultati della validazione lato server resi dopo il ricaricamento della pagina o iniettati dinamicamente nel DOM.

Un pass richiede che: (1) ogni campo in errore sia associato a livello programmatico a un messaggio di errore — tipicamente tramite aria-describedby o aria-errormessage — in modo che le tecnologie assistive possano annunciarlo; (2) il messaggio di errore sia in testo semplice visibile nell’interfaccia (non nascosto agli utenti vedenti); e (3) il testo descriva chiaramente cosa è andato storto, non solo che qualcosa è andato storto. Ad esempio, «L’indirizzo email è obbligatorio» è una descrizione di errore valida, mentre mostrare solo un bordo rosso o un’icona di punto esclamativo senza alternativa testuale è un fail.

Si ha un fail quando: gli errori sono indicati solo tramite cambiamenti di colore (bordo rosso senza testo), gli errori sono annunciati solo tramite role="alert" senza identificare quale campo è interessato, il testo del messaggio di errore è vuoto o generico (ad es. «Input non valido»), oppure i messaggi di errore esistono nel DOM ma non sono collegati a livello programmatico al campo corrispondente, quindi i lettori di schermo non possono associarli.

WCAG 3.3.1 non si applica quando non avviene alcun rilevamento automatico — per esempio, se un form viene inviato e il server si limita a ricaricare la pagina senza alcuna indicazione di cosa sia andato storto, questo è un diverso problema di usabilità ma rientra al di fuori dell’ambito stretto di questo criterio. Tuttavia, se il tuo sistema esegue una rilevazione automatica (come praticamente tutti i form moderni), il criterio è pienamente in ambito. Non sono definite eccezioni all’interno del criterio stesso per tipi di input o casi d’uso specifici.

Perché È Importante

L’identificazione degli errori influisce direttamente in modo significativo su più gruppi di persone con disabilità. Per gli utenti ciechi e ipovedenti che si affidano a lettori di schermo come NVDA, JAWS o VoiceOver, un bordo rosso o un’icona di avviso non comunicano nulla. Se un messaggio di errore non è presente come testo effettivo e non è associato a livello programmatico al campo in errore, il lettore di schermo non lo annuncerà e l’utente potrebbe inviare un form ripetutamente senza capire perché fallisce. Secondo l’Organizzazione Mondiale della Sanità, circa 2,2 miliardi di persone nel mondo hanno una qualche forma di disabilità visiva e milioni si affidano quotidianamente alla tecnologia assistiva per interagire con i contenuti web.

Per gli utenti con disabilità cognitive — inclusa dislessia, disturbo da deficit di attenzione e compromissioni della memoria — messaggi di errore vaghi come «Qualcosa è andato storto» creano barriere significative. Questi utenti traggono enorme beneficio da testo di errore preciso e descrittivo che indichi esattamente quale campo necessita di correzione e quale dovrebbe essere il formato o il valore corretto. Ad esempio, invece di «Data non valida», un messaggio come «La data di nascita deve essere nel formato GG/MM/AAAA» è molto più utilizzabile.

Gli utenti con disabilità motorie che navigano tramite tastiera o dispositivi a sensore spendono uno sforzo significativo per muoversi all’interno di un form. Quando un errore è poco chiaro o non identificato, devono ripercorrere l’intero form per trovare il problema, aumentando notevolmente il costo cognitivo e fisico del completamento del form. Un’identificazione chiara degli errori consente a questi utenti di saltare direttamente al campo problematico.

Considera questo scenario reale: una cittadina o un cittadino turco che tenta di registrarsi su un portale di e-service governativo per richiedere un beneficio di invalidità. Il form richiede un numero di ID nazionale in un formato specifico. L’utente, che è cieco, inserisce il proprio numero di ID. Al momento dell’invio, il form si ricarica con campi evidenziati in rosso ma senza alcun testo di errore associato. Il lettore di schermo annuncia solo le etichette dei campi di nuovo — l’utente non ha idea di cosa sia andato storto o quale campo sia il problema. Abbandona completamente il processo, perdendo l’accesso a un servizio pubblico critico. Questa è esattamente la situazione che WCAG 3.3.1 è progettata per prevenire.

Oltre all’accessibilità, un’identificazione chiara degli errori migliora i tassi di conversione e l’usabilità per tutti gli utenti. Studi di ricerca UX mostrano costantemente che messaggi di errore in linea descrittivi riducono l’abbandono dei form. Da una prospettiva SEO, segnali di coinvolgimento utente migliorati — inclusi tempi di permanenza più lunghi sul sito e invii di form andati a buon fine — influenzano positivamente il posizionamento nei motori di ricerca nel tempo.

Regole Axe-core Correlate

WCAG 3.3.1 richiede test manuali per una verifica completa. Questo perché gli strumenti automatici possono rilevare la presenza o l’assenza di pattern strutturali (come aria-describedby o aria-errormessage), ma non possono valutare se il contenuto testuale di un messaggio di errore sia significativo, accurato o sufficiente ad aiutare l’utente a comprendere e correggere l’errore. Uno strumento automatico vede che esiste un elemento con role="alert"; non può giudicare se il messaggio «Errore alla riga 4» descriva adeguatamente un errore di validazione a un utente di lettore di schermo.

  • aria-required-attr: Questa regola di axe-core verifica che gli elementi con determinati ruoli ARIA abbiano tutti gli attributi ARIA richiesti. Pur non essendo esclusivamente una regola di identificazione degli errori, è rilevante perché un campo di form in stato di errore che usa role="textbox" o simili senza gli attributi richiesti può non riuscire a trasmettere le informazioni di stato alle tecnologie assistive, compromettendo la comunicazione dell’errore.
  • aria-valid-attr-value: Questa regola segnala i casi in cui gli attributi ARIA fanno riferimento a ID che non esistono nel DOM. Ad esempio, se un campo usa aria-describedby="email-error" ma non esiste alcun elemento con id="email-error", l’associazione è interrotta e il messaggio di errore non verrà letto dai lettori di schermo. Questo è un pattern di fallimento comune per la 3.3.1.
  • Requisito di valutazione manuale: I tester devono attivare manualmente gli errori di validazione e poi usare un lettore di schermo per confermare che: il campo in errore sia identificato per nome o etichetta, la descrizione dell’errore venga annunciata, il messaggio sia significativo e azionabile e l’errore non sia comunicato solo tramite mezzi non testuali. Le scansioni automatiche non possono simulare sequenze di interazione utente né valutare la qualità semantica del testo del messaggio, rendendo il giudizio umano indispensabile per questo criterio.

Come Testare

  1. Scansione automatica con axe DevTools o Lighthouse: Esegui una scansione con axe DevTools sulla pagina che contiene il form prima e dopo aver attivato gli errori di validazione. Cerca in particolare violazioni relative a riferimenti aria-describedby o aria-errormessage interrotti, regioni role="alert" o aria-live mancanti usate per l’iniezione dinamica degli errori e campi del form privi di etichette (che impediscono anche una corretta associazione degli errori). In Lighthouse, controlla l’audit Accessibilità per violazioni relative ai form. Nota che un report automatico pulito non conferma la conformità alla 3.3.1 — esclude solo alcuni fallimenti strutturali.
  2. Test manuale di navigazione da tastiera: Usando solo la tastiera (Tab, Shift+Tab, Invio, Spazio), prova a inviare il form con valori intenzionalmente errati o mancanti. Verifica che: il focus si sposti sul primo campo in errore o vicino ad esso, ogni messaggio di errore sia visibile nel viewport e i messaggi di errore identifichino il campo specifico per nome e descrivano il problema in testo semplice.
  3. Test con lettore di schermo NVDA + Firefox: Apri il form in Firefox con NVDA attivo. Invia il form con errori. Ascolta con attenzione: NVDA annuncia quale campo ha un errore? La descrizione dell’errore viene letta ad alta voce? Spostati con Tab nel campo errato — NVDA legge il messaggio di errore associato come parte della descrizione accessibile del campo? Se usi regioni aria-live, verifica che l’annuncio non sia ritardato o soppresso.
  4. Test con lettore di schermo VoiceOver + Safari (macOS/iOS): Ripeti lo stesso processo usando VoiceOver su Safari. Usa VO+Freccia destra per leggere il form dopo l’invio. Conferma che ogni campo in errore includa il testo di errore nel suo nome o descrizione accessibile. Su iOS, testa usando la navigazione touch e i gesti di scorrimento.
  5. Test con lettore di schermo JAWS + Chrome: Con JAWS in esecuzione in Chrome, invia il form con errori. Usa il cursore virtuale di JAWS per navigare fino a ciascun campo del form in errore. Conferma che il testo del messaggio di errore sia incluso nella lettura del campo da parte di JAWS. Controlla anche il comportamento della modalità form di JAWS, poiché la modalità form sopprime alcuni annunci delle regioni live.
  6. Verifica di colore e indizi non testuali: Ispeziona visivamente ogni stato di errore. Rimuovi o disabilita temporaneamente il CSS (usando gli strumenti di sviluppo del browser o un bookmarklet) e conferma che l’identificazione dell’errore sia ancora presente come testo nel DOM. Questo verifica che la comunicazione dell’errore non si basi esclusivamente su colore o iconografia.
  7. Verifica dell’iniezione dinamica: Per single-page application o form con validazione in tempo reale, usa gli strumenti di sviluppo del browser per ispezionare il DOM dopo che un errore è stato attivato. Conferma che l’elemento del messaggio di errore esista nel DOM, contenga testo non vuoto e sia referenziato dall’input corrispondente tramite aria-describedby o aria-errormessage.

Come Correggere

Scenario 1: Errore indicato solo dal colore — Non corretto

<!-- Fail: red border added via class, no error text associated -->
<label for='email'>Email Address</label>
<input type='email' id='email' name='email' class='input-error'>
<!-- CSS sets border: 2px solid red on .input-error -->
<!-- No error message text is rendered in the DOM -->

Scenario 1: Errore indicato solo dal colore — Corretto

<!-- Pass: error text is present, visible, and linked to the input -->
<label for='email'>Email Address</label>
<input
  type='email'
  id='email'
  name='email'
  class='input-error'
  aria-describedby='email-error'
  aria-invalid='true'
>
<!-- aria-invalid signals the error state to assistive technologies -->
<!-- aria-describedby links the input to its error message by ID -->
<p id='email-error' role='alert'>
  Please enter a valid email address, for example: [email protected]
</p>

Scenario 2: Riepilogo generico dell’errore senza identificazione del campo — Non corretto

<!-- Fail: a summary alert exists but does not identify which fields failed -->
<div role='alert'>
  <p>There are errors in the form. Please correct them and try again.</p>
</div>
<label for='phone'>Phone Number</label>
<input type='tel' id='phone' name='phone' class='is-invalid'>
<!-- No per-field error message; user cannot determine which field failed -->

Scenario 2: Riepilogo generico dell’errore senza identificazione del campo — Corretto

<!-- Pass: summary lists specific fields in error, and each field has inline error text -->
<div role='alert' aria-labelledby='error-heading'>
  <h2 id='error-heading'>2 errors found. Please fix the following:</h2>
  <ul>
    <li><a href='#phone'>Phone Number: must contain only digits and be 10 characters long</a></li>
    <li><a href='#dob'>Date of Birth: required field — please enter your date of birth</a></li>
  </ul>
</div>
<label for='phone'>Phone Number</label>
<input
  type='tel'
  id='phone'
  name='phone'
  aria-describedby='phone-error'
  aria-invalid='true'
>
<!-- Inline error linked via aria-describedby -->
<p id='phone-error'>Phone Number must contain only digits and be 10 characters long.</p>

Scenario 3: Riferimento aria-describedby interrotto — Non corretto

<!-- Fail: aria-describedby references an ID that does not exist in the DOM -->
<label for='username'>Username</label>
<input
  type='text'
  id='username'
  name='username'
  aria-describedby='username-msg'
  aria-invalid='true'
>
<!-- The element with id='username-msg' was never rendered or was removed -->
<!-- Screen readers find no target and announce nothing for the description -->

Scenario 3: Riferimento aria-describedby interrotto — Corretto

<!-- Pass: the referenced element exists in the DOM with matching ID -->
<label for='username'>Username</label>
<input
  type='text'
  id='username'
  name='username'
  aria-describedby='username-msg'
  aria-invalid='true'
>
<!-- Element with matching id is present and contains descriptive text -->
<span id='username-msg'>
  Username must be between 4 and 20 characters and contain only letters and numbers.
</span>

Scenario 4: Errore di validazione in tempo reale iniettato dinamicamente — Non corretto

<!-- Fail: error injected into DOM but not associated with input; no live region -->
<label for='password'>Password</label>
<input type='password' id='password' name='password'>
<!-- After blur, JavaScript appends this element, but no aria-describedby on input -->
<div class='error-text'>Password is too short.</div>

Scenario 4: Errore di validazione in tempo reale iniettato dinamicamente — Corretto

<!-- Pass: error container pre-exists in DOM (empty), input references it; aria-live announces changes -->
<label for='password'>Password</label>
<input
  type='password'
  id='password'
  name='password'
  aria-describedby='password-error'
  aria-invalid='false'
>
<!-- Empty span present at page load; JavaScript populates text and sets aria-invalid='true' on error -->
<span id='password-error' aria-live='polite'></span>
<!-- JavaScript on blur: -->
<!-- document.getElementById('password-error').textContent = 'Password must be at least 8 characters.'; -->
<!-- document.getElementById('password').setAttribute('aria-invalid', 'true'); -->

Errori Comuni

  • Usare solo modifiche di classe CSS (ad es. aggiungendo border-color: red) per indicare errori senza alcun testo corrispondente nel DOM. Il solo colore non è percepibile dagli utenti ciechi o con daltonismo e viola sia 3.3.1 che 1.4.1.
  • Scrivere aria-describedby sull’input ma puntare a un ID che viene reso in modo condizionale o rimosso dal DOM al reset della validazione. Il riferimento interrotto significa che il lettore di schermo non trova contenuto associato e l’errore è di fatto invisibile agli utenti di tecnologie assistive.
  • Usare il testo del placeholder come unico messaggio di errore. Il testo del placeholder scompare quando l’utente inizia a digitare, è spesso a basso contrasto e non viene annunciato in modo affidabile da tutti i lettori di schermo come parte della descrizione del campo durante gli stati di errore.
  • Iniettare messaggi di errore dinamicamente nel DOM senza assicurarsi che siano associati al loro campo padre tramite aria-describedby. Un messaggio di errore visivamente adiacente non è automaticamente associato a un input — il collegamento programmatico deve essere esplicito.
  • Mostrare un riepilogo di errore a livello di pagina senza collegare ogni elemento del riepilogo al campo specifico in errore. Gli utenti di lettori di schermo o di navigazione da tastiera devono poter passare direttamente dalla descrizione dell’errore al campo che richiede correzione.
  • Impostare aria-invalid='true' su un campo ma non fornire alcun testo di messaggio di errore. L’attributo aria-invalid segnala che un campo è in stato di errore ma non descrive l’errore — deve essere combinato con un messaggio descrittivo.
  • Fornire messaggi di errore troppo generici, come «Input non valido» o «Errore nel campo». Queste descrizioni non spiegano cosa non va o come risolverlo, non soddisfano il requisito descrittivo della 3.3.1 e rendono inutilmente difficile la correzione degli errori per tutti gli utenti.
  • Rimuovere le regioni aria-live o role='alert' dai contenitori di errore quando si reimposta un form, facendo scomparire i contenitori prima che i lettori di schermo abbiano finito di annunciarne il contenuto. Gli annunci degli errori possono essere interrotti, lasciando l’utente ignaro del risultato della validazione.
  • Affidarsi alle bolle di validazione native del browser (i popup di tooltip predefiniti del browser) senza personalizzazione. Le interfacce di validazione native del browser sono incoerenti tra browser e combinazioni di tecnologie assistive e spesso non soddisfano i requisiti WCAG per identificazione e descrizione in scenari di form complessi.
  • Posizionare i messaggi di errore visivamente lontano dai campi associati — ad esempio solo in un riquadro di avviso nell’intestazione — senza fornire anche messaggi in linea vicino a ciascun campo. Gli utenti ipovedenti che ingrandiscono lo schermo potrebbero non vedere l’avviso a livello di intestazione mentre sono focalizzati sull’area di input e gli utenti di tastiera devono percorrere una distanza significativa per leggere l’errore.

Relazione con le Normative di Accessibilità della Turchia

La Circolare Presidenziale 2025/10 della Turchia, pubblicata nella Gazzetta Ufficiale n. 32933 il 21 giugno 2025, stabilisce requisiti obbligatori di accessibilità web per un’ampia gamma di entità che operano in Turchia. La circolare adotta WCAG 2.2 come standard tecnico, rendendo tutti i criteri di successo di Livello A — inclusa WCAG 3.3.1 Error Identification — legalmente obbligatori per le organizzazioni interessate.

La tempistica di conformità stabilita dalla circolare è di un anno per le istituzioni pubbliche e due anni per le entità del settore privato dalla data di pubblicazione. Ciò significa che le istituzioni pubbliche devono raggiungere la conformità a WCAG 2.2 Livello A entro giugno 2026 e le entità coperte del settore privato entro giugno 2027.

Le entità coperte dalla circolare includono un’ampia sezione trasversale dei servizi digitali turchi. Le istituzioni pubbliche — incluse tutti i ministeri del governo centrale, i comuni, le università statali e le agenzie pubbliche — sono tenute a garantire che i loro servizi digitali siano accessibili. Nel settore privato, la circolare copre piattaforme di e-commerce, banche e istituzioni finanziarie, ospedali e fornitori di assistenza sanitaria privati, società di telecomunicazioni con 200.000 o più abbonati, agenzie di viaggio, compagnie di trasporto private e scuole private autorizzate dal Ministero dell’Istruzione Nazionale (MoNE).

Per tutte queste entità, WCAG 3.3.1 è direttamente rilevante ovunque vengano utilizzati form online — il che in pratica significa quasi ogni punto di contatto digitale. I form di checkout dell’e-commerce, i flussi di apertura di conti bancari, i portali di registrazione dei pazienti degli ospedali, i form di richiesta di benefici governativi, i sistemi di prenotazione di compagnie aeree e autobus e le pagine di iscrizione scolastica si basano tutti sulla validazione dei form. Se uno qualsiasi di questi sistemi rileva automaticamente un errore di input e non identifica il campo o non descrive l’errore in forma testuale, è in violazione diretta dei requisiti della circolare.

La non conformità alla circolare può esporre le entità interessate a controlli regolatori, rischi reputazionali e potenziali sanzioni man mano che il quadro di applicazione dell’accessibilità digitale della Turchia matura. Oltre alla conformità legale, l’adesione alla 3.3.1 dimostra un impegno verso un’erogazione di servizi inclusiva — garantendo che tutti i cittadini, incluse le circa 8,5 milioni di persone con disabilità in Turchia (secondo i dati TÜİK), possano accedere ai servizi essenziali online senza barriere. Le organizzazioni che operano nell’ambito del framework SDK di Accsible dovrebbero dare priorità sia alla conformità strutturale automatizzata sia a test manuali approfonditi per garantire che la gestione degli errori soddisfi pienamente questo criterio fondamentale.