Questa è la traduzione dell'articolo Have a Field Day with HTML5 Forms di Inayaili de León pubblicato originariamente su 24 Ways il 3 Dicembre 2009.
I form sono in genere visti come qualcosa di fastidioso su cui lavorare, sia per quel che riguarda il markup sia per quel che riguarda gli stili. Io non sono d'accordo: i form (come le tabelle) sono qualcosa su cui è divertente lavorare.
In questo articolo vedremo come creare un bel form seguendo le definizioni di HTML5 per il markup e tecniche avanzate dei CSS (compresi i CSS3). Sono certa che alla fine della lettura vorrete anche voi creare un form in questo modo.
Ecco cosa realizzeremo:
Le icone usate sono prese da Chalkwork Payments.
Un markup semantico
Andremo a lavorare su un modulo per i pagamenti. Ci sono tre sezioni principali:
- I dettagli sulla persona che compila il modulo
- I dettagli sull'indirizzo
- I dettagli sulla carta di credito
Useremo anche alcuni dei nuovi tipi di input e attributi per gli input di HTML5 per creare campi semanticamente più corretti e usare meno classi e id. In particolare useremo:
email
per il campo destinato all'indirizzo e-mail;tel
per il campo destinato al numero di telefono;number
per i dettagli relativi alla carta di credito e al codice di sicurezza;required
per contrassegnare i campi obbligatori;placeholder
per le indicazioni di compilazione all'interno di alcuni campi;autofocus
per assegnare automaticamente il focus al primo campo quando la pagina viene caricata.
Ci sono molti altri tipi di input e di attributi nella specifica HTML5. Per approfondire si può fare riferimento alla pagina dedicata ai form HTML5 sul sito del W3C. Credo che possa essere sufficiente per darvi un'idea di quanto possa essere divertente lavorare sul markup dei form secondo la nuova specifica.
Lavorare sulle basi
Ciascuna sezione del form sarà racchiusa all'interno di un fieldset
. Nel caso dei radio-button destinati alla scelta del tipo di carta, racchiuderemo le opzioni in un altro fieldset
annidato. Useremo anche una lista ordinata per raggruppare ciascuna coppia input/label. Ciò ci fornirà una sorta di aggancio semantico per gli stili da applicare e renderà anche più semplice la lettura del form quando ad esso non sono applicati stili:
Ecco dunque il markup su cui lavoreremo:
<form id=payment>
<fieldset>
<legend>Your details</legend>
<ol>
<li>
<label for=name>Name</label>
<input id=name name=name type=text placeholder="First and last name" required autofocus>
</li>
<li>
<label for=email>Email</label>
<input id=email name=email type=email placeholder="example@domain.com" required>
</li>
<li>
<label for=phone>Phone</label>
<input id=phone name=phone type=tel placeholder="Eg. +447500000000" required>
</li>
</ol>
</fieldset>
<fieldset>
<legend>Delivery address</legend>
<ol>
<li>
<label for=address>Address</label>
<textarea id=address name=address rows=5 required></textarea>
</li>
<li>
<label for=postcode>Post code</label>
<input id=postcode name=postcode type=text required>
</li>
<li>
<label for=country>Country</label>
<input id=country name=country type=text required>
</li>
</ol>
</fieldset>
<fieldset>
<legend>Card details</legend>
<ol>
<li>
<fieldset>
<legend>Card type</legend>
<ol>
<li>
<input id=visa name=cardtype type=radio>
<label for=visa>VISA</label>
</li>
<li>
<input id=amex name=cardtype type=radio>
<label for=amex>AmEx</label>
</li>
<li>
<input id=mastercard name=cardtype type=radio>
<label for=mastercard>Mastercard</label>
</li>
</ol>
</fieldset>
</li>
<li>
<label for=cardnumber>Card number</label>
<input id=cardnumber name=cardnumber type=number required>
</li>
<li>
<label for=secure>Security code</label>
<input id=secure name=secure type=number required>
</li>
<li>
<label for=namecard>Name on card</label>
<input id=namecard name=namecard type=text placeholder="Exact name as on the card" required>
</li>
</ol>
</fieldset>
<fieldset>
<button type=submit>Buy it!</button>
</fieldset>
</form>
Abbellire le cose
Per prima cosa, iniziamo aggiungendo alcune impostazioni di default al nostro form resettando i margini e il padding degli elementi e aggiungendo un font di default per la pagina:
html, body, h1, form, fieldset, legend, ol, li {
margin: 0;
padding: 0;
}
body {
background: #ffffff;
color: #111111;
font-family: Georgia, "Times New Roman", Times, serif;
padding: 20px;
}
Poi passiamo a dare uno stile all'elemento form
che racchiude tutti i campi:
form#payment {
background: #9cbc2c;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
padding: 20px;
width: 400px;
}
Rimuoviamo anche il bordo dai fieldset
e applichiamo un po' di margine inferiore. Usando la pseudo-classe :last-of-type
rimuoviamo il margine inferiore dall'ultimo fieldset
perché non ne abbiamo bisogno:
form#payment fieldset {
border: none;
margin-bottom: 10px;
}
form#payment fieldset:last-of-type {
margin-bottom: 0;
}
A questo punto rendiamo grandi ed evidenti gli elementi legend
. Applichiamo pure un'ombreggiatura di un verde chiaro per evidenziare questo dettaglio:
form#payment legend {
color: #384313;
font-size: 16px;
font-weight: bold;
padding-bottom: 10px;
text-shadow: 0 1px 1px #c0d576;
}
Ora le nostre legend
hanno un magnifico aspetto. Ma perché non aggiungere una chiara indicazione dei passi necessari per compilare il form? Invece di aggiungere tale indicazione manualmente ad ogni legend
, possiamo usare dei contatori automatici.
Per aggiungere un contatore ad un elemento dobbiamo usare le pseudo-classi :before
e :after
per aggiungere contenuto attraverso i CSS. Seguiremo questi passi:
- creaiamo un contatore usando la proprietà
counter-reset
sull'elementoform
; - richiamiamo il contatore con la proprietà
content
usando lo stesso nome dato in precedenza; - con la proprietà
counter-increment
indichiamo che per ogni elemento che corrisponde al nostro selettore il contatore sarà incrementato di 1.
form#payment > fieldset > legend:before {
content: "Step " counter(fieldsets) ": ";
counter-increment: fieldsets;
}
Infine, dobbiamo cambiare lo stile della legend
che fa parte del gruppo dei radio-button, per farla apparire visivamente come una label
:
form#payment fieldset fieldset legend {
color: #111111;
font-size: 13px;
font-weight: normal;
padding-bottom: 0;
}
Applicare gli stili alle liste
Per le nostre liste useremo solo dei bordi arrotondati, un bordo semi-trasparente e uno sfondo. Dato che usiamo colori RGBa, dovremmo fornire anche un'opzione alternativa per i browser che non li supportano (va messa prima della definizione dei colori RGBa). Per le liste annidate elimineremo queste proprietà perché si sovrapporebbero alle altre:
form#payment ol li {
background: #b9cf6a;
background: rgba(255,255,255,.3);
border-color: #e3ebc3;
border-color: rgba(255,255,255,.6);
border-style: solid;
border-width: 2px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
line-height: 30px;
list-style: none;
padding: 5px 10px;
margin-bottom: 2px;
}
form#payment ol ol li {
background: none;
border: none;
float: left;
}
Controlli dei form
Ora dobbiamo solo applicare gli stili agli elementi label
, input
e button
.
Tutte le label avranno lo stesso aspetto, tranne quella dei radio-button. Floatteremo tutte le label a sinistra e assegneremo a ciascuna una larghezza.
Per le label dei tipi di carta di credito aggiungeremo come sfondo un'icona ed elimineremo alcune delle proprietà che non sono necessarie. Useremo il selettore di attributo per specificare l'immagine di sfondo per ciascuna label (in questo caso useremo l'attributo for
di ogni label).
Per aggiungere un dettaglio extra, assegneremo un cursore specifico (cursor: pointer
) alle label dei radio-button per lo stato di :hover
: in questo modo l'utente sa che può semplicemente cliccare per selezionare un'opzione.
form#payment label {
float: left;
font-size: 13px;
width: 110px;
}
form#payment fieldset fieldset label {
background:none no-repeat left 50%;
line-height: 20px;
padding: 0 0 0 30px;
width: auto;
}
form#payment label[for=visa] {
background-image: url(visa.gif);
}
form#payment label[for=amex] {
background-image: url(amex.gif);
}
form#payment label[for=mastercard] {
background-image: url(mastercard.gif);
}
form#payment fieldset fieldset label:hover {
cursor: pointer;
}
Ci siamo quasi. Per quanto riguarda gli elementi input
, vogliamo applicare uno stile a tutti i campi, tranne ai radio-button. Useremo per questo scopo la pseudo-classe :not()
. Grazie a quest'ultima possiamo identificare tutti gli input
tranne quelli che hanno un type
uguale a radio
.
Faremo anche in modo di aggiungere degli stili per lo stato di :focus
e per i radio-button:
form#payment input:not([type=radio]),
form#payment textarea {
background: #ffffff;
border: none;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
-khtml-border-radius: 3px;
border-radius: 3px;
font: italic 13px Georgia, "Times New Roman", Times, serif;
outline: none;
padding: 5px;
width: 200px;
}
form#payment input:not([type=submit]):focus,
form#payment textarea:focus {
background: #eaeaea;
}
form#payment input[type=radio] {
float: left;
margin-right: 5px;
}
Per concludere, il pulsante di invio. Useremo su button
una bella tipografia e un'ombreggiatura sul testo, allineeremo tutto al centro del form e assegneremo colori di sfondo diversi a seconda dello stato:
form#payment button {
background: #384313;
border: none;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
-khtml-border-radius: 20px;
border-radius: 20px;
color: #ffffff;
display: block;
font: 18px Georgia, "Times New Roman", Times, serif;
letter-spacing: 1px;
margin: auto;
padding: 7px 25px;
text-shadow: 0 1px 1px #000000;
text-transform: uppercase;
}
form#payment button:hover {
background: #1e2506;
cursor: pointer;
}
Finito!
Il form non avrà lo stesso aspetto su tutti i browser. Internet Explorer non supporta gli angoli arrotondati, come le versioni non ultime di Opera; i nuovi tipi di input sono resi come campi normali su alcuni browser; alcune delle funzionalità più avanzate dei CSS che abbiamo usato non sono supportate da tutti i navigatori. Ciò non significa che non possiate usarli sin da ora e semplificare il vostro processo di sviluppo.