I moduli sono il punto in cui il tuo sito smette di parlare e inizia ad ascoltare: richieste di contatto, ordini, registrazioni, ricerche. Sono anche il punto in cui l'accessibilità fallisce più spesso. Lo studio WebAIM Million, che ogni anno analizza il milione di home page più visitate, trova con regolarità label mancanti sui campi dei moduli in quasi la metà dei casi, il che ne fa uno degli errori di accessibilità più comuni del web. La parte frustrante: i moduli accessibili non sono difficili. Una manciata di attributi HTML, usati correttamente, decide se una persona non vedente riesce a mandarti un messaggio oppure rinuncia in silenzio, e se il tuo modulo rispetta le WCAG, che lo European Accessibility Act ha reso un obbligo di legge per molte imprese. Questa guida attraversa le cinque cose che contano, con markup pronto da copiare, e si chiude con uno sguardo onesto ai plugin per moduli di WordPress.
Perché i moduli sono il problema di accessibilità più grande?
Chi vede e usa il mouse legge un modulo come un insieme visivo: il testo accanto a una casella appartiene evidentemente a quella casella, il bordo rosso significa evidentemente un errore. Le tecnologie assistive non hanno nulla di questo contesto. Chi usa uno screen reader passa da un controllo all'altro con il tabulatore e sente solo ciò che il markup collega esplicitamente a ciascun campo. Se il collegamento manca, la persona sente campo di testo, vuoto, e deve indovinare cosa vuole quel campo. Chi usa il controllo vocale affronta un problema parallelo: dire clicca email funziona solo se il campo si chiama email a livello di programma.
È questo il principio alla base di ogni regola di questa guida: ogni relazione visiva in un modulo deve esistere anche nel markup. Label e campo, suggerimento e campo, errore e campo, gruppo e opzioni. I criteri di successo WCAG rilevanti (1.3.1 Info and Relationships, 3.3.1 Error Identification, 3.3.2 Labels or Instructions) si riducono tutti a quest'unica idea.
Come etichettare correttamente i campi di un modulo
Le fondamenta di ogni modulo accessibile sono l'elemento label, collegato al proprio campo tramite l'attributo for che punta all'id del campo:
<label for="email">Indirizzo email</label>
<input type="email" id="email" name="email" autocomplete="email">
<!-- Suggerimento aggiuntivo, collegato tramite aria-describedby -->
<label for="password">Password</label>
<input type="password" id="password" name="password" aria-describedby="password-hint">
<p id="password-hint">Almeno dodici caratteri.</p>Questo ti compra tre cose in un colpo solo: gli screen reader annunciano la label quando il campo riceve il focus, cliccare sulla label porta il focus sul campo (un'area di tocco più grande su mobile, a vantaggio di tutti) e il controllo vocale può rivolgersi al campo chiamandolo per nome. Suggerimenti e istruzioni di formato vanno in un elemento separato referenziato da aria-describedby, così vengono annunciati dopo la label senza affollarla. L'attributo autocomplete è un bonus discreto: per i campi che raccolgono dati personali le WCAG 1.3.5 lo chiedono, e permette ai browser di compilare correttamente il campo, cosa che aiuta soprattutto chi ha limitazioni motorie e cognitive. Il tutorial del W3C sui moduli copre ogni variante di questi schemi.
Perché un placeholder non è una label
Il campo con il solo placeholder è l'errore dall'aspetto accessibile più diffuso del web. Sembra pulito e fallisce in quattro modi contemporaneamente:
- Il testo sparisce quando si digita. La descrizione svanisce proprio quando l'utente sta lavorando con il campo. Chiunque abbia dimenticato cosa chiedeva un campo compilato a metà l'ha provato sulla propria pelle.
- Il grigio predefinito non rispetta il contrasto. Lo stile tipico dei placeholder non raggiunge il rapporto di contrasto 4,5:1 che le WCAG richiedono per il testo.
- Il supporto delle tecnologie assistive è incoerente. Alcune combinazioni di screen reader e browser annunciano i placeholder, altre no. Una label viene annunciata da tutte.
- I campi compilati sembrano vuoti, quelli vuoti sembrano compilati. Chi scorre il modulo per capire cosa manca legge esattamente il contrario.
I placeholder vanno benissimo come complemento, per esempio come esempio di formato tipo nome@example.com dentro un campo etichettato come si deve. Come unica descrizione di un campo, sono un fallimento del criterio WCAG 3.3.2 con una bella tipografia.
Come contrassegnare i campi obbligatori in modo accessibile
Due canali, sempre insieme. Il canale macchina è l'attributo HTML required, che fa annunciare il campo come obbligatorio a browser e screen reader e abilita la validazione nativa. Il canale umano è il testo visibile: la parola obbligatorio (o il suo contrario, facoltativo) nella label. Il popolare asterisco rosso da solo fallisce su entrambi i fronti: il colore da solo non può veicolare informazione (WCAG 1.4.1) e la convenzione dell'asterisco, se comunque la usi, va perlomeno spiegata sopra il modulo e inclusa nella label per essere annunciata.
<label for="name">Nome (obbligatorio)</label>
<input type="text" id="name" name="name" required>Un'inversione pragmatica produce spesso i moduli più puliti: se quasi ogni campo è obbligatorio, contrassegna solo quelli facoltativi e dillo sopra il modulo. E il campo obbligatorio migliore è quello che elimini; ogni campo che un modulo non chiede è un campo che non può essere compilato male.
Come rendere accessibili i messaggi di errore
La gestione degli errori è il punto in cui i moduli perdono gli utenti che non hanno ancora perso. Il criterio WCAG 3.3.1 richiede che gli errori siano identificati sotto forma di testo e descritti all'utente. Lo schema solido per ogni campo:
<label for="email">Indirizzo email (obbligatorio)</label>
<input type="email" id="email" name="email" required
aria-invalid="true" aria-describedby="email-error">
<p id="email-error" class="error">
Inserisci un indirizzo email, per esempio nome@example.com.
</p>I pezzi: aria-invalid="true" contrassegna il campo come errato così che gli screen reader annuncino inserimento non valido quando riceve il focus, il messaggio è testo vero (non solo un bordo rosso, non solo un'icona) ed è legato al campo con aria-describedby, e il testo dice come risolvere il problema, non solo che esiste. Errore, correggi non aiuta nessuno; Inserisci una data nel formato GG.MM.AAAA sì.
Per la validazione che scatta all'invio conta un passaggio in più: dopo un invio fallito, sposta il focus da tastiera sul primo campo errato, oppure genera in cima un riepilogo degli errori con role="alert" e i link ai campi coinvolti. Chi usa uno screen reader, invia e non sente nulla, presume che il modulo abbia funzionato. Il silenzio dopo un invio fallito è il bug dei moduli più crudele che esista.
Fieldset e legend: raggruppare radio button e checkbox
I gruppi di radio button e checkbox hanno una struttura a due livelli: il gruppo ha una domanda, ogni opzione ha una label. Entrambi i livelli devono stare nel markup, e gli elementi nativi per il livello del gruppo sono fieldset e legend:
<fieldset>
<legend>Metodo di contatto preferito (obbligatorio)</legend>
<input type="radio" id="contact-email" name="contact" value="email">
<label for="contact-email">Email</label>
<input type="radio" id="contact-phone" name="contact" value="phone">
<label for="contact-phone">Telefono</label>
</fieldset>Senza il fieldset, chi usa uno screen reader ed entra nel gruppo con il tabulatore sente solo Email, radio button, uno di due, e non ha idea di quale domanda rispondano le opzioni. Con il fieldset, la legend viene annunciata per prima. La stessa struttura serve per i gruppi di checkbox e vale la pena mantenerla anche quando un design system ridisegna gli elementi fino a renderli irriconoscibili; la semantica non costa nulla e porta tutto.
I plugin per moduli di WordPress sono accessibili?
Perlopiù possono esserlo, e nessuno di loro lo garantisce. Il quadro onesto plugin per plugin: Contact Form 7 restituisce qualsiasi cosa tu scriva nel suo template del modulo, quindi label, fieldset e collegamento degli errori sono interamente nelle tue mani; la flessibilità che lo rende popolare rende anche facile pubblicare moduli senza label. Gravity Forms ha rifatto il proprio markup con l'accessibilità come obiettivo dichiarato qualche anno fa e nelle versioni attuali produce un output solido. WPForms ha investito allo stesso modo in impostazioni predefinite accessibili. In ogni caso tre cose possono comunque rompere un plugin accessibile: lo stile del tuo tema (contorni del focus rimossi, contrasto distrutto), i CAPTCHA (una barriera del tutto inaccessibile; gli approcci honeypot evitano il problema) e i tipi di campo personalizzati aggiunti sopra.
Quindi prova il risultato generato, non la pagina di marketing. La versione da due minuti: stacca il mouse e completa il modulo solo con la tastiera, controllando di vedere il focus a ogni passaggio, poi invialo vuoto e verifica se i messaggi di errore vengono annunciati e raggiunti. I validatori automatici come WAVE intercettano in pochi secondi la metà strutturale, label mancanti comprese.
Come InspectWP ti aiuta a trovare i problemi dei moduli
Il report di InspectWP esamina il tuo sito WordPress come lo vede un browser, e diversi controlli riguardano direttamente i moduli. Segnala i moduli la cui action invia a un indirizzo HTTP non sicuro, un problema che i browser puniscono con avvisi esattamente nel momento in cui un visitatore sta per affidarti i suoi dati. Oltre a questo, il report copre i fondamentali di accessibilità attorno ai tuoi moduli: immagini senza attributo alt, la gerarchia delle intestazioni con cui si orienta chi usa uno screen reader ed errori in console che spesso rivelano script di validazione rotti. Un report gratuito è una prima passata veloce sulla pagina in cui vive il tuo modulo.