Form HTML
Input, validazione nativa, accessibilità e stile dei moduli web. I form sono il principale punto di interazione tra utente e server.
L'Elemento Form
<form> è il contenitore per tutti gli elementi che raccolgono dati. Due attributi fondamentali: action (dove inviare i dati) emethod (come inviarli — GET o POST).
<form action="/submit" method="POST">
<!-- elementi del form qui -->
<button type="submit">Submit</button>
</form>GET: i dati appaiono nell'URL (?q=search). Usa per ricerche e filtri — il risultato è linkabile. POST: i dati vanno nel body HTTP. Usa per login, registrazioni e acquisti — più sicuro per dati sensibili.
Input e Tipi
<input> è l'elemento più versatile dei form. L'attributotype ne definisce comportamento, validazione automatica e tastiera mobile.
type="text"
Free text — default
type="email"
Validates email format
type="password"
Hidden text
type="number"
Numbers only
type="tel"
Phone number
type="url"
Validates URL format
type="search"
Search field with ×
type="date"
Native date picker
type="time"
Native time picker
type="color"
Color picker
type="range"
Min/max slider
type="file"
File upload
type="checkbox"
Multiple selection
type="radio"
Single selection
type="hidden"
Hidden field
<!-- Attributi comuni -->
<input type="text" name="username" placeholder="John Doe">
<input type="email" name="email" placeholder="john@example.com">
<input type="password" name="password" minlength="8">
<input type="number" name="age" min="18" max="99">
<input type="date" name="birthdate" min="1900-01-01">
<input type="range" name="volume" min="0" max="100" step="5">
<input type="color" name="color" value="#0EA5E9">Label e Accessibilità
Ogni input deve avere una <label> associata. È fondamentale per l'accessibilità: gli screen reader annunciano il campo, e cliccando sulla label il focus va direttamente all'input.
<!-- METODO 1: for/id — raccomandato -->
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<!-- METODO 2: wrapper — alternativa valida -->
<label>
Email address
<input type="email" name="email">
</label>
<!-- ❌ SBAGLIATO: il placeholder non è una label -->
<input type="email" placeholder="email@example.com">
<!-- nessuna label = inaccessibile! -->Il placeholder scompare non appena l'utente inizia a digitare — non usarlo mai come sostituto della label. È solo un suggerimento opzionale, non un'etichetta permanente.
Fieldset e Legend
<fieldset> raggruppa campi correlati. <legend>fornisce un titolo al gruppo, annunciato dagli screen reader come contesto per tutti i campi interni.
<form>
<fieldset>
<legend>Personal information</legend>
<label for="first-name">First name</label>
<input type="text" id="first-name" name="first-name">
<label for="last-name">Last name</label>
<input type="text" id="last-name" name="last-name">
</fieldset>
<fieldset>
<legend>Preferred contact method</legend>
<label>
<input type="radio" name="contact" value="email"> Email
</label>
<label>
<input type="radio" name="contact" value="phone"> Phone
</label>
</fieldset>
</form>Select, Textarea, Checkbox e Radio
<!-- SELECT: menu a tendina con gruppi opzionali -->
<select name="country" id="country">
<optgroup label="Europe">
<option value="it">Italy</option>
<option value="ch">Switzerland</option>
</optgroup>
<optgroup label="America">
<option value="us">United States</option>
</optgroup>
</select>
<!-- TEXTAREA: testo su più righe -->
<textarea name="bio" id="bio" rows="5"
placeholder="Tell us about yourself..."></textarea>
<!-- CHECKBOX: selezione multipla (name diversi) -->
<label><input type="checkbox" name="css" value="css"> CSS</label>
<label><input type="checkbox" name="js" value="js"> JavaScript</label>
<!-- RADIO: selezione singola (STESSO name) -->
<label><input type="radio" name="level" value="beginner"> Beginner</label>
<label><input type="radio" name="level" value="intermediate"> Intermediate</label>
<label><input type="radio" name="level" value="advanced"> Advanced</label>name identifica il campo nel form inviato. I radio button con lo stessoname formano un gruppo esclusivo — uno solo può essere selezionato.
Validazione HTML5
HTML5 offre validazione nativa senza JavaScript. Il browser controlla i campi prima dell'invio e mostra messaggi di errore nella lingua del sistema.
<!-- Attributi di validazione -->
<input type="text" name="username" required>
<input type="email" name="email" required>
<input type="text" name="username" minlength="3" maxlength="20">
<input type="number" name="age" min="18" max="99">
<input type="text" name="zip" pattern="[0-9]{5}" title="5 digits">
<input type="url" name="website" required>/* Pseudo-classi per feedback visivo */
input:valid { border-color: #22c55e; }
input:invalid { border-color: #ef4444; }
/* Solo dopo l'interazione dell'utente (browser moderni) */
input:user-valid { border-color: #22c55e; }
input:user-invalid { border-color: #ef4444; }
/* Campi obbligatori */
input:required { border-left: 3px solid #0EA5E9; }La validazione HTML5 migliora l'UX ma non è sicurezza. Chiunque può bypassarla modificando il DOM. Valida sempre i dati anche lato server.
Stilizzare i Form
I form hanno stili di default che variano tra browser. Una reset di base li rende coerenti e controllabili da CSS.
/* Reset base per tutti gli elementi form */
input,
textarea,
select,
button {
font-family: inherit;
font-size: inherit;
line-height: inherit;
margin: 0;
-webkit-appearance: none;
appearance: none;
}
/* Mostra sempre un indicatore di focus visibile */
input:focus,
textarea:focus,
select:focus {
outline: 2px solid #0EA5E9;
outline-offset: 2px;
}
/* ❌ Non farlo mai senza un sostituto visivo */
/* input:focus { outline: none; } */
/* Layout a griglia per form a due colonne */
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.form-grid .full-width {
grid-column: 1 / -1;
}Rimuovere outline: none senza sostituirlo rende il sito inaccessibile per chi usa solo la tastiera. È un requisito WCAG — sostituiscilo sempre con un indicatore visivamente chiaro.
Editor Interattivo
Un form di contatto completo con stili responsive. Prova ad aggiungere nuovi campi, cambiare i tipi di input o sperimentare con la validazione nativa.
Esercizi
✏️Metti in pratica
Esercizio A — Base
Form di Registrazione
Crea un form con:
- First name e Last name su una riga (CSS Grid
repeat(2, 1fr)) - Email e Password (
required,minlength="8") - Data di nascita (
type="date") - Checkbox per i termini di servizio
- Bottone submit stilizzato
Esercizio B — Intermedio
Sondaggio con Fieldset
Crea un sondaggio con tre sezioni <fieldset>:
- Personal info (name, email, age)
- Experience level (radio: Beginner / Intermediate / Advanced)
- Interests (checkbox: HTML, CSS, JavaScript, Design)
Esercizio C — Avanzato
Form Responsive e Accessibile
Crea un form completo che:
- Su mobile: colonna singola; su desktop: griglia a 2 colonne
- Usa
:user-valid/:user-invalidper feedback visivo - Focus sempre visibile (niente
outline: nonesenza sostituto) - Ogni campo ha
labelconfor/idcorrispondenti