La personalizzazione grafica degli elementi dei form con Javascript (ma anche con i CSS...) è da sempre oggetto di discussione. Più che mai oggi, con l'abbondanza di soluzioni rese possibili dai tanti framework per effetti spuntati negli ultimi due anni.
Rispetto all'usabilità e all'accessibilità, la preoccupazione maggiore è relativa alla resa e al funzionamento degli elementi sottoposti al maquillage grafico in condizioni particolari, a partire da quei browser che non abbiano il supporto a Javascript o che lo abbiano disabilitato. Mai, quindi, si dovrebbe scegliere tra quelle disponibili e rintracciate in rete una soluzione che non sia ispirata al principio della graceful degradation o che non si basi sui dettami del cosiddetto Javascript non intrusivo. Detto altrimenti: se senza Javascript il form perde il suo accattivante aspetto grafico, ma funziona ugualmente assumendo il suo aspetto normale, di default, va bene, altrimenti meglio lasciar perdere. Per altre considerazioni in merito vi rimando a questo post di Alessandro Fulciniti uscito tempo fa su Edit e ai relativi commenti.
In questo articolo segnaleremo delle soluzioni relative alla personalizzazione grafica di checkbox (e in parte di radiobutton), elementi che a differenza di altri come i campi di testo poco si prestano alla modifica dell'aspetto via CSS (cosa che spiega l'abbondanza di script che li riguardano). Ne approfitteremo per cercare di fornire anche delle linee guida basilari che possano servire nella scelta di questa o quella soluzione.
Partiamo con uno script basato su jQuery: jQuery Checkbox. Ecco il primo esempio. Come si vede, il classico checkbox è stato sostituito da due piccoli asterischi, grigio per lo stato unchecked
, giallo per checked
(trovate le due immagini insieme a tutti gli esempi nel pacchetto zip allegato all'articolo).
L'uso del plugin è di una semplicità disarmante, anche perché non è richiesto, nella configurazione di base, l'utilizzo di CSS. Il codice parla da sé. Nella sezione head
andiamo a richiamare i due script fondamentali:
<script src="jquery-1.1.3.1.pack.js" type="text/javascript"></script>
<script src="jquery.checkbox.js" type="text/javascript"></script>
Una semplice istruzione Javascript serve a inizializzare l'effetto (va nel body
della pagina):
<script type="text/javascript">
$(function(){
$("#checkbox").checkbox({checked: "asterisk_yellow.jpg", unchecked: "asterisk_gray.jpg"});
});
</script>
Non bisogna fare altro che specificare l'URL delle due immagini da usare, rispettivamente, per lo stato checked
e per lo stato unchecked
dei checkbox
. Nel nostro caso, tramite l'uso dei selettori di jQuery, l'effetto è applicato a tutti i checkbox che si trovano all'interno del form con id="checkbox"
, indicato nella funzione con #checkbox
. Questa la parte HTML:
<form method="post" action="/" id="checkbox">
<fieldset>
<legend>Il mio form</legend>
<ol>
<li><input type="checkbox" name="chk1" id="chk1" /> check 1</li>
<li><input type="checkbox" name="chk2" id="chk2" /> check 2</li>
<li><input type="checkbox" name="chk3" id="chk3" /> check 3</li>
</ol>
</fieldset>
</form>
Tutto qui. Lo script degrada bene, come si vede nello screenshot qui sotto, con Javascript disabilitato:
Partendo da questa base è possibile personalizzare a piacere l'aspetto dei checkbox usando altre immagini, come è stato fatto per il secondo esempio. Riportiamo semplicemente la parte del codice modificata rispetto al primo:
<script type="text/javascript">
$(function(){
$("#checkbox").checkbox({checked: "spunta.gif", unchecked: "nospunta.gif"});
});
</script>
Nella scelta delle immagini si dovrà sempre prestare attenzione alle dimensioni (devono essere uguali) e al loro rapporto in grandezza con il testo circostante.
Ora torniamo un attimo indietro al codice HTML del primo esempio:
<form method="post" action="/" id="checkbox">
<fieldset>
<legend>Il mio form</legend>
<ol>
<li><input type="checkbox" name="chk1" id="chk1" /> check 1</li>
<li><input type="checkbox" name="chk2" id="chk2" /> check 2</li>
<li><input type="checkbox" name="chk3" id="chk3" /> check 3</li>
</ol>
</fieldset>
</form>
Si può notare che i checkbox sono racchiusi all'interno di elementi li
nel contesto di una lista ordinata. Potevano anche essere semplicemente separati con un <br />
, non è questo il punto. La questione cruciale è che manca un elemento considerato importante nella realizzazione di form accessibili: label
.
Proviamo allora a modificare il nostro form aggiungendo l'etichetta (esempio 3):
<form method="post" action="/" id="checkbox">
<fieldset>
<legend>Il mio form</legend>
<input type="checkbox" name="chk1" id="chk1" /><label for="chk1"> check 1</label><br />
<input type="checkbox" name="chk2" id="chk2" /><label for="chk2"> check 2</label><br />
<input type="checkbox" name="chk3" id="chk3" /><label for="chk3"> check 3</label><br />
</fieldset>
</form>
A questo punto dovrebbe accadere una cosa: il checkbox dovrebbe poter essere spuntato anche cliccando sul testo della label. Ma provando l'esempio è facile verificare che così non avviene. L'autore lo riconosce esplicitamente, per cui non è nemmeno giusto parlare di bug: di una limitazione si tratta. Lo stesso autore propone anche una soluzione con supporto delle label, ma che però non degrada bene con Javascript disabilitato (anche qui per sua onesta ammissione).
Tutto ciò dimostra come nella vautazione di uno script particolare si debbano sempre prendere in considerazione tutti gli aspetti (lungi da me l'intenzione di criticare gratuitamente il lavoro altrui). Se si è soddisfatti e convinti della facilità d'uso e non si hanno preoccupazioni in merito all'accessibilità e rispetto all'uso delle label, lo script è perfetto.
Una soluzione che concilia graceful degradation e rispetto delle regole di accessibilità cui si è accennato è rappresentata da FancyForm (basata su MooTools). Oltre che sui checkbox consente di modificare anche l'aspetto dei radiobutton.
L'implementazione è piuttosto semplice. Per certi versi l'unica vera differenza è rappresentata dalla necessità di ricorrere a poche righe di CSS. Ecco il quarto esempio.
Nella sezione head
invochiamo i due script principali:
<script type="text/javascript" src="mootools.v1.11.js"></script>
<script type="text/javascript" src="moocheck.js"></script>
Passiamo poi a definire le tre regole CSS di cui abbiamo bisogno:
<style type="text/css">
#checkbox label{display:block;
padding-left:32px;
background-position:8px center;
background-repeat:no-repeat;
clear:both;
cursor:pointer}
.checked{background-image:url(asterisk_gray.jpg)}
.unchecked{background-image:url(asterisk_yellow.jpg)}
</style>
Per prima cosa, utilizzando label
, impostiamo alcune proprietà che ci consentiranno di avere un buon posizionamento del checkbox rispetto al testo (padding-left
, in primis) e di modificare l'aspetto del cursore quando si passa col mouse sull'etichetta.
Importantissime sono le definizioni per le classi .checked
e .unchecked
. Qui impostamo l'URL delle immagini che andranno a sostituire il checkbox di default.
Non ci resta che definire il codice HTML:
<form method="post" action="/" id="checkbox">
<fieldset>
<legend>Il mio form</legend>
<label><input type="checkbox" name="chk1" id="chk1" /> check 1</label><br />
<label><input type="checkbox" name="chk2" id="chk2" /> check 2</label><br />
<label><input type="checkbox" name="chk3" id="chk3" /> check 3</label><br />
</fieldset>
</form>
Tutto funziona alla perfezione, con e senza Javascript.
Altre soluzioni
Chiudiamo con una piccola lista di soluzione alternative:
- Custom Checkboxes & Radio Buttons
- Niceforms (consente di intervenire su tutti i tipi di input)
- NiceJForms (porting per jQuery del precedente)