I form sono il punto in cui un sito smette di essere solo da leggere e chiede qualcosa all'utente: un contatto, un acquisto, una registrazione. Sono anche il punto in cui si perdono più utenti, per campi confusi, errori incomprensibili o tastiere sbagliate sul telefono. E sono una porta d'ingresso per dati non fidati. Un buon form deve essere insieme chiaro, accessibile e robusto.
Ogni campo ha la sua etichetta
Il segnaposto (placeholder) non è un'etichetta. Sparisce appena l'utente inizia a scrivere, spesso ha un contrasto basso e non sempre viene letto dalle tecnologie assistive. Ogni campo ha bisogno di un label collegato:
<label for="email">Indirizzo email</label>
<input id="email" name="email" type="email" autocomplete="email" required>
L'attributo for deve corrispondere all'id del campo. Il collegamento ha anche un vantaggio pratico: toccando l'etichetta si attiva il campo, utile per caselle di controllo e pulsanti di opzione piccoli.
Per gruppi di opzioni correlate usa fieldset e legend:
<fieldset>
<legend>Come preferisci essere contattato?</legend>
<label><input type="radio" name="contatto" value="email"> Email</label>
<label><input type="radio" name="contatto" value="telefono"> Telefono</label>
</fieldset>
Il tipo di input giusto
L'attributo type non è un dettaglio estetico. Sui dispositivi mobili cambia la tastiera e in tutti i browser abilita controlli nativi:
| Tipo | Effetto principale |
|---|---|
email |
tastiera con @, verifica del formato |
tel |
tastierino numerico telefonico |
url |
tastiera con / e .com, verifica del formato |
number |
valori numerici con frecce di incremento |
date |
selettore di data nativo |
search |
campo di ricerca con pulsante di cancellazione |
Attenzione a number: è pensato per quantità, non per codici. Per CAP, numeri di carta o codici di verifica usa type="text" con inputmode="numeric", che mostra il tastierino senza aggiungere frecce e senza eliminare gli zeri iniziali.
Autocomplete: meno digitazione, meno errori
L'attributo autocomplete dice al browser che tipo di dato è richiesto, così può proporre i valori salvati. Valori come name, email, tel, street-address, postal-code, country, cc-number, new-password e current-password sono standardizzati.
Usarli correttamente fa risparmiare tempo a tutti ed è particolarmente utile a chi ha difficoltà motorie. Per i campi password, new-password permette ai gestori di password di suggerire una password robusta, mentre current-password facilita l'accesso.
Validazione nel browser
HTML offre validazione nativa con attributi come required, minlength, maxlength, min, max e pattern:
<label for="cap">CAP</label>
<input id="cap" name="cap" inputmode="numeric"
pattern="[0-9]{5}" required
aria-describedby="cap-aiuto">
<p id="cap-aiuto">Cinque cifre, per esempio 95100.</p>
Puoi personalizzare lo stile dei campi non validi con la pseudo-classe :user-invalid, che si attiva solo dopo che l'utente ha interagito con il campo, evitando di mostrare errori in rosso su un form appena aperto.
Messaggi di errore utili
Un buon messaggio di errore dice cosa non va e come correggerlo. "Campo non valido" non aiuta; "La data deve essere successiva a oggi" sì. Altri accorgimenti:
- mostra l'errore vicino al campo, collegato tramite
aria-describedby; - segnala il campo con
aria-invalid="true"; - non affidarti solo al colore: aggiungi un testo o un'icona con testo alternativo;
- dopo l'invio, se ci sono errori, porta il focus sul primo campo errato o su un riepilogo all'inizio del form;
- non cancellare i dati già inseriti quando il form viene rifiutato.
La validazione nel browser non è sicurezza
Tutto ciò che avviene nel browser può essere aggirato: chiunque può modificare l'HTML, disattivare JavaScript o inviare una richiesta direttamente al server. La validazione lato client serve all'usabilità; la sicurezza richiede di ripetere ogni controllo sul server.
Sul server:
- verifica tipo, lunghezza e formato di ogni campo, rifiutando ciò che non è previsto;
- usa query parametrizzate per il database, mai concatenazione di stringhe;
- codifica i dati quando li mostri in una pagina, per evitare il cross-site scripting;
- per i caricamenti di file, verifica dimensione e tipo reale e salva i file fuori dalla cartella pubblica, con nomi generati dal server;
- proteggi i form che modificano dati con token anti-CSRF o con cookie
SameSiteadeguati.
Proteggersi dallo spam senza punire gli utenti
I form pubblici attirano invii automatici. Prima di ricorrere a un CAPTCHA, che pesa sull'accessibilità e sull'esperienza, prova misure meno invasive:
- un campo "trappola" nascosto agli utenti tramite CSS, che i bot tendono a compilare: se ha un valore, l'invio viene scartato;
- un controllo sul tempo di compilazione: un form completato in meno di un secondo difficilmente è umano;
- limiti di frequenza per indirizzo o per sessione sul server.
<div class="nascosto" aria-hidden="true">
<label for="sito">Lascia vuoto questo campo</label>
<input id="sito" name="sito" tabindex="-1" autocomplete="off">
</div>
Il tabindex="-1" e aria-hidden evitano che chi naviga da tastiera o con un lettore di schermo finisca per sbaglio nel campo trappola.
Chiedi solo ciò che serve
Ogni campo in più riduce le probabilità che il form venga completato e aumenta i dati personali da custodire. Se un'informazione non è indispensabile, eliminala o rendila facoltativa e segnala chiaramente quali campi sono obbligatori.
In sintesi
- Ogni campo ha un
labelcollegato; ilplaceholdernon lo sostituisce. - Usa il
typee l'autocompletecorretti per tastiere adatte e compilazione rapida. - Scrivi messaggi di errore specifici, collegati al campo e non basati solo sul colore.
- La validazione nel browser aiuta l'utente; la sicurezza si fa sul server.
- Contro lo spam prova campi trappola e limiti di frequenza prima dei CAPTCHA.