Creare forms sia belli che accessibili può richiedere molto tempo. In particolare, i problemi sorgono, quando label e input sono adiacenti a delle immagini. Di solito di usavano le Tabelle, che funzionano bene in questi casi, ma i form non sono dati che andrebbero in una tabella, c'è un errore semantico.
Ho provato a trovare una soluzione portabile e accessibile per dare stile ai form (nel senso posso applicare il codice ad un oggetto come ad un altro). Ho trovato la soluzione utilizzando oggetti Flottanti, ma data la complessità di certi layout e i numerosi bug di internet explorer nella gestione del Float, non è facile tirar su una soluzione flottante. Vorrei creare qualcosa che chiunque e facilmente possa usare in ogni progetto: Un foglio di stile che, applicato alla giusta pagina HTML, produrrà il layout base. Ecco cosa intendevo per portabilità.
La cosa più importante è l'HTML che utilizziamo per costruire il form. Fortunatamente l'HTML ha tanti Tag che ci permettono di creare un form accessibile, per esempio fieldset, legend, e label.
Se non conosci questi tag ecco un breve riepilogo:
L'elemento fieldset ti permette di raggruppare i campi in pezzettoni, porzioni. Con legend possiamo dare un nome-etichetta al fieldset, che aiuta gli utenti a capire il contesto dei campi nei fieldset.
In alcuni Screen reader, la legend è associata ad ogni campo all'interno di un fieldset e viene letta ad ogni click del tasto TAB, questo è molto utile per i disabili.
l'elemento label serve a dare informazioni su uno specifico campo e al tempo stesso rafforza il legame tra le informazioni da immettere nel campo e l'elemento campo stesso.
Vediamo un semplice esempio del fieldset:
<fieldset>
<legend>Informazioni di spedizione</legend>
<ol>
<li>
<label for="name">Nome<em>*</em></label>
<input id="name" />
</li>
<li>
<label for="address1">Indirizzo<em>*</em></label>
<input id="address1" />
</li>
<li>
<label for="address2">Indirizzo 2</label>
<input id="address2" />
</li>
<li>
<label for="town-city">Paese/Città</label>
<input id="town-city" />
</li>
<li>
<label for="county">Nazione<em>*</em></label>
<input id="county" />
</li>
<li>
<label for="postcode">CAP<em>*</em></label>
<input id="postcode" />
</li>
<li>
<fieldset>
<legend>è questo l’indirizzo di »
fatturazione ?<em>*</em></legend>
<label><input type="radio" »
name="invoice-address" /> Certo</label>
<label><input type="radio" »
name="invoice-address" /> NO</label>
</fieldset>
</li>
</ol>
</fieldset>
L'HTML è molto semplice, ma ti sarai accorto di alcune cose nella struttura, c’è una lista ordinara, <ol>, nel fieldset principale. Questo per due motivi:
li come contenitore per ogni riga del form, che sarebbe difficile da realizzare.
Inoltre, il tag <ol> fornisce delle informazioni addizionali che van bene per certi altri screen reeader che dicono il numero della riga quando arrivano sulla lista.
Questo è l'approccio che dà la massima accessibilità e aiuta gli utenti assistiti da macchine.
Questa è la parte divertente, il mio obbiettivo era produrre un foglio di stile principale che possa essere aggiornato per dare al form le strutture stilistiche basilari di cui abbiam bisogno. Ebbene, ecco:
form.cmxform fieldset {
margin-bottom: 10px;
}
form.cmxform legend {
padding: 0 2px;
font-weight: bold;
}
form.cmxform label {
display: inline-block;
line-height: 1.8;
vertical-align: top;
}
form.cmxform fieldset ol {
margin: 0;
padding: 0;
}
form.cmxform fieldset li {
list-style: none;
padding: 5px;
margin: 0;
}
form.cmxform fieldset fieldset {
border: none;
margin: 3px 0 0;
}
form.cmxform fieldset fieldset legend {
padding: 0 0 5px;
font-weight: normal;
}
form.cmxform fieldset fieldset label {
display: block;
width: auto;
}
form.cmxform em {
font-weight: bold;
font-style: normal;
color: #f00;
}
form.cmxform label {
width: 120px; /* Width of labels */
}
form.cmxform fieldset fieldset label {
margin-left: 123px; /* Width plus 3 (html space) */
}
Come vedi lo stile è basilare e chi ha occhio avrà notato che l’opzione di visualizzazione dei label è impostata su "inline-block".
Questo è il bello e la buona notizia è che funziona sia con Internet Explorer per Windows che per Mac. Per dirla tutta è meglio puntualizzare che con IE per windows funziona soltanto con elementi che già sono di default "inline" e i label lo sono. La cattiva notizia è che i browser basati su Mozilla (Firefox, Netscape,ecc.) non supportano direttamente questa proprietà, però, tra breve vedremo come fare anche in questo caso.
Quindi, questo è il nucleo richiesto per avere un form dall’aspetto basilare.
Volevo anche creare un CSS che si comportasse come parte di una libreria fatta di regole riutilizzabili e con gli stili base per un form. In teoria, queste regole non andrebbero modificate da uno sviluppatore, ma semplicemente inserite in un sito. Gli autori possono modificare un elemento dichiarando un selettore più specifico o sovrascrivendo quelli già dichiarati. Ma se volessero proprio personalizzare tutto il form potrebbero comunque inserire un foglio di stile separato come ho fatto io in questo, form di esempio.
Come ho detto sopra, gli utenti di Mozilla non vedranno quello che vedono tutti gli altri. Sfortunatamente, Mozilla non supporta correttamente la visualizzazione "inline-block", che in realtà è solo parte del problema. Comunque, mozzilla a un valore specifico per questo tipo di visualizzazione ed è "-moz-inline-box", che si comporta, quasi sempre, come "inline-block". Il problema è che se hai un label molto lungo il testo scompare sotto i campi del form. Il testo non và a capo se si trova all'interno di un elemento "-moz-inline-box". Ma se mettiamo il testo dentro un elemento visualizzato come "block" che si trova a sua volta in quello "-moz-inline-block" e gli diamo una larghezza "width", tutto và bene.
Perché aggiungere tutto questo codice a mano nel documento ? in effetti, rovinerà tutto il nostro bellissimo, chiaro e significativo HTML !
Inoltre potremmo decidere di cambiare il layout del sito e sarebbe una bella scocciatura tutto quel codice.
Per fortuna, c’è un modo più elegante per risolvere il problema, basta usare JavaScript e il DOM:
if( document.addEventListener ) »
document.addEventListener( 'DOMContentLoaded', cmxform, false);
function cmxform(){
// Hide forms
$( 'form.cmxform' ).hide().end();
// Processing
$( 'form.cmxform' ).find( 'li/label' ).not( '.nocmx' ) »
.each( function( i ){
var labelContent = this.innerHTML;
var labelWidth = document.defaultView. »
getComputedStyle( this, '' ).getPropertyValue( 'width' );
var labelSpan = document.createElement( 'span' );
labelSpan.style.display = 'block';
labelSpan.style.width = labelWidth;
labelSpan.innerHTML = labelContent;
this.style.display = '-moz-inline-box';
this.innerHTML = null;
this.appendChild( labelSpan );
} ).end();
// Show forms
$( 'form.cmxform' ).show().end();
}
Per semplificare il tutto JavaScript può usare la fantastica libreria JQuery (che naturalmente và inclusa).
Per prima cosa nascondo i campi che usano la classe "cmxform"
// Hide forms
$( 'form.cmxform' ).hide().end();
Facciam questo altrimenti gli utenti potrebbero vedere il form mentre viene generato e poi sistemato dal javaScript.
Coem seconda cosa, usando i metodi JQuery, una combinazione di selettori CSS e XPath, raccolgo tutte le label che non hanno classe "nocmx" e incluse nei tag "li".
$( 'form.cmxform' ).find( 'li/label' ).not( '.nocmx' ) »
.each( function( i ){
...
Uso "nocmx" come un filtro, non per dare a quei campi uno stile diverso, ma perché è utile per questo metodo. Poi, per ogni label raccolta, viene creato uno span che sistema il problema dell’inline-box.
$( 'form.cmxform' ).find( 'li/label' ).not( '.nocmx' ) »
.each( function( i ){
...
}
Infine il form è di nuovo reso visibile e non ci sono erroti.
// Show forms
$( 'form.cmxform' ).show().end();
Nota: Sto usando il metodo document.addEventListener() per lanciare lo script, questo è l'ideale perché funziona solo con Mozilla e l'errore sarà corretto solo per questo browser.
JavaScript potrebbe non sembrare la soluzione più elegante, ma in questo caso non è intrusivo e, se viene disabilitato, il form non perde la sua funzionalità.
C'è ancora qualcosa da sistemare per IE, per windows, dobbiam sistemare la posizione delle "legend" con un valore negativo dei margini sinistro e destro, come qui sotto:
form.cmxform legend {
padding: 0 2px;
font-weight: bold;
_margin: 0 -7px; /* IE Win */
}
Per IE5/Mac, dobbiam sistemare la visualizzazione del legend, a causa di un bug, aggiungendo quanto segue:
/*\*//*/
form.cmxform legend {
display: inline-block;
}
/* IE Mac legend fix */
queste regole permettono di supplire a regole specifiche per IE/Mac. Se non ti piace usare regole in questo modo sentiti libero di rimuoverle.
Puoi aggiungere dei foglie di stile esterni, ma io ho preferito far così per mantenere la portabilità, cosi tutto era in un unico posto.
Ecco fatto. Tutto quello che devi fare è includere il file "cmxform" e aggiungere la classe "cmxform" ad ogni campo che lo necessiti. (se ti stai chiedendo da dove viene questo nome "cmxform" è presto detto, ho sviluppato questa tecnica mentre lavoravo per la Cimex Media a Londra) Buon divertimento !
Nota: Questa tecnica è stato testata con Safari 2.0.3, Firefox 1.5, Opera 8,5, Internet Explorer 7b2, Internet Explorer 6, internet explorer 5 (win), Internet explorer 5.2 (mac), Netscape 7.2(mac) e Netscape 8.1 (win).
Nick Rigby è un libero professionista e sviluppatore di web accessibile e conforme agli standard, lavora nella compagnia Puretic. Oltre al lavoro gli piace il football, la musica, l'essere creativo e scrivere occasionalmente articoli per nickrigby.com