Una delle attività più impegnative associate alla creazione di una pagina HTMLW è senz'altro quella dedicata all'impostazione del layout (inteso come aspetto grafico e posizionamento degli oggetti) di un modulo (o form) interattivo.
Un modulo è una sezione di una pagina HTML contenente sia del testo formattato mediante i tag (o marcatori) tipici del medesimo linguaggio ipertestuale, che elementi speciali chiamati controlli (caselle di spunta, pulsanti, pulsanti radio, menu, caselle di testo, ecc.) ed etichette associate agli stessi.
Gli utenti generalmente compilano un modulo modificandone i controlli: digitano testo, selezionano caselle di spunta o menù, ecc. Successivamente i dati contenuti nel modulo possono essere inviati ad una procedura (ospitata da un host server) che li elabora e restituisce un risultato che di norma è costituito da una nuova pagina HTML.
L'obiettivo di questo documento, che vuole essere il primo di una serie dedicati appunto a questa tipologia di argomento, è quello di fornire alcuni suggerimenti su come definire correttamente l'aspetto grafico ed il posizionamento del controllo input utilizzando gli strumenti messi disposizione dai fogli di stileW a cascata (CSS), dando per scontato che i lettori abbiano una conoscenza di base sia di questi ultimi che del linguaggio HTML.
Il passato
Fino a qualche anno fà, era estremamente semplice per gli sviluppatori realizzare moduli HTML con un layout gradevole e ordinato: era sufficiente creare delle tabelle ad hoc, posizionando all'interno delle celle i controlli desiderati, assegnando loro il corretto allineamento sia verticale che orizzontale e formattandone opportunatamente gli attributi relativi all'aspetto tipografico (tipo di carattere, dimensione, colore di primo piano e di sfondo, ecc.).
L'utilizzo dei tag destinati alla rappresentazione tabellari dei dati (<table>, <th>, <tr>, <td>, ecc.) per organizzare il layout (e quindi il posizionamento) degli oggetti all'interno di una pagina è però formalmente scorretto e assolutamente deprecato dalle indicazioni del W3CW (World WideWeb Consortium). In aggiunta a ciò l'uso di tabelle per la formattazione dell'aspetto di un modulo, non consente di separare lo stesso dal suo contenuto per consentire un'agevole aggiornamento futuro del layout stesso.
Il presente
I fogli di stile a cascata consentono di superare entrambi i limiti collegati all'errato utilizzo delle tabelle per l'impostazione dell'aspetto di un modulo: ne rendono superfluo l'ausilio e consentono di separarne l'impostazione grafica dal contenuto.
Con la semplice ridefinizione delle classi associate ai controlli all'interno del foglio di stile associato ad una pagina HTML o ad un template, è possibile far assumere ad essi l'aspetto grafico desiderato in maniera semplice ed immediata.
Ad esempio, ridefinendo all'interno del CSS le classi:
input { font-size: 12px; padding: 2px; margin: 0px 5px }
textarea { font-size: 10px; padding: 2px; margin: 5px 5px }
assegneremo a tutti i controlli input e textarea presenti nella (o nelle) pagina (pagine) associate, le caratteristiche tipografiche e di marginatura indicate, senza dovere effettuare alcuna modifica al codice HTML contenuto.
Il tag <input>
Uno dei problemi maggiori che si incontrano nella definizione delle classi da associare ai controlli dei moduli è soprattutto dovuto al fatto che con il tag <input ...> è possibile definire diverse tipologie di oggetto con caratteristiche grafiche completamente diverse tra loro.
Infatti, a seconda del valore assegnato alla proprietà type, è possibile definire:
| Campo di testo a riga singola |
<input type="text" ... /> |
| Campo di testo nascosto (password) |
<input type="password" ... /> |
| Casella di spunta |
<input type="checkbox" ... /> |
| Pulsanti radio |
<input type="radio" ... /> |
| Pulsante di inoltro |
<input type="submit" ... /> |
| Pulsante di inoltro grafico |
<input type="image" ... /> |
| Pulsante di ripristino |
<input type="reset" ... /> |
| Pulsante di comando |
<input type="button" ... /> |
| Campo di testo nascosto |
<input type="hidden" ... /> |
| Controllo per la selezione di file |
<input type="file" ... /> |
Ciò vuol dire che, prendendo come riferimento l'esempio precedente, se all'interno delle nostre pagine sono presente dei controlli relativi a pulsanti, campi di testo, caselle di spunta, ecc., essi avranno tutti lo stesso aspetto grafico, poichè vengono ereditati gli attributi della stessa classe input.
A questo fastidioso inconveniente si può facilmente ovviare definendo delle classi specifiche per ciascuna tipologia associata a tale controllo (i nomi utilizzati sono puramente indicativi e possono essere assegnati a piacere):
input .button { font-size: 10px; padding: 2px; margin: 0px 5px; border: solid 1px #000000 }
input .checkbox { font-size: 8px; padding: 2px; margin: 5px }
input .text { font-size: 12px; padding: 2px; margin: 0px 5px; line-height: 16px }
avendo cura di andare a ridefinire gli attributi significativi per la tipologia del controllo desiderato, dato che, altrimenti, erediterebbero quelli preimpostati con la ridefinizione della classe input stessa.
Sfortunatamente questa strategia costringe ad assegnare ad ogni controllo inserito all'interno del codice HTML, la classe specifica, costringendo lo sviluppatore ad un lavoro più attento nella fase di codifica. Quindi, in riferimento all'esempio di cui sopra si dovranno inserire i relativi tag, nel seguente modo:
<input type="button" class="button" ... />
...
<input type="checkbox" class="checkbox" ... />
...
<input type="text" class="text" ... />
Nel caso in cui si debba creare un foglio di stile da applicare ex-novo ad una collezione di pagine HTML esistente, tutto il processo diventa quindi più impegnativo perchè:
- E' necessario agire sul sorgente HTML e verificare che i vari controlli non abbiano già delle classi assegnate: in tal caso ridefinire le stesse all'interno del CSS con le opportune personalizzazioni.
- Se ai controlli non sono associate classi, è necessario farlo, dopo aver definito una convenzione di denominazioni per individuare le varie casistiche.
L'attività diventa quindi più complessa e onerosa in termini di dispendio temporale. Fortunatamente, è possibile superare questo inconveniente ricorrendo ad una definizione più specifica delle classi associate ai tag, potendone specificare anche la tipologia. Per cui, l'esempio precedente può essere sostituito con:
input[type=button] { font-size: 10px; padding: 2px; margin: 0px 5px; border: solid 1px #000000 }
input[type=checkbox] { font-size: 8px; padding: 2px; margin: 5px }
input[type=text] { font-size: 12px; padding: 2px; margin: 0px 5px; line-height: 16px }
In questo modo è possibile indicare in maniera del tutto trasparente al codice HTML l'aspetto di tutti i controlli presenti in esso e relativi alle tipologie specificate, anche in presenza di definizioni di stile già assegnate agli stessi. E' interessante notare come, con questa tecnica, sia possibile assegnare classi differenti ad oggetti sostanzialmente uguali, quali possono essere i pulsanti di inoltro (submit), di ripristino (reset) o generici.
Nel caso in cui si volesse assegnare un aspetto grafico diverso per ciascun modulo utilizzato all'interno della nostra collezione di pagine è sufficiente incapsularlo in una coppia di tag <div ..> ... </div> ed assegnare a questo una classe specifica da definire opportunamente nel CSS associato.
Ipotizzando, ad esempio, di avere due form di cui uno dedicato all'invio di commenti e l'altro all'invio di una richiesta di assistenza:
<div class="comment">
...
<input type="text" ... />
...
</div>
...
<div class="contact">
...
<input type="text" ... />
...
</div>
Il CSS associato dovrebbe contenere delle definizioni simili alle seguenti:
div.comment input[type=text] { font-size: 12px; padding: 2px; margin: 0px 5px; line-height: 16px }
...
div.contact input[type=text] { font-size: 10px; padding: 2px; margin: 0px; line-height: 14px}
(eventualmente può anche essere omessa l'assegnazione della classe al tag div)
Il rovescio della medaglia: la retrocompatibilità
Sfortunatamente la metodologia descritta ha un limite: non viene correttamente riconosciuta dalle versioni di Internet Explorer precedenti alla 7.0, mentre funziona correttamente con FireFox, Opera e tutti i browser basati sui motori di rendering di questi ultimi.
In realtà è possibile far interpretare correttamente anche ad Internet Explorer 6 e precedenti la sintassi descritta, ma è necessario ricorrere ad un hack che fa uso di codice JavascriptW e, francamente, non credo che ne valga la pena (perchè ricorrere ad un escamotage per rendere compatibile un browser ad uno standard de facto definito dal W3C), anche se il parco installato della vecchia release del browser Microsoft è, purtroppo, drammaticamente ancora consistente.
Ad ogni modo è possibile trovare in rete diverse soluzioni risolutive al problema: io stesso tempo fa avevo realizzato qualcosa di simile ma preferisco indirizzare su questa soluzione (che però non ho direttamente sperimentato) chiunque voglia approfondire l'argomento.