⌨️ Sviluppo web

Form HTML accessibili e sicuri: validazione e buone pratiche

Come costruire form HTML usabili da tutti: etichette, tipi di input, autocomplete, messaggi di errore, validazione nel browser e sul server, antispam.

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 SameSite adeguati.

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 label collegato; il placeholder non lo sostituisce.
  • Usa il type e l'autocomplete corretti 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.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche