Nel nostro primo seminario abbiamo visto come convertire un documento da un formato non-(X)HTML al formato (X)HTML. In questo seminario vedremo come modificare il layout di un documento HTML partendo da una struttura molto semplice, che andremo progressivamente a modificare e a formattare con i fogli di stile. Vedremo inoltre come aumentare l'accessibilità del documento fornendo all'utente la possibilità di modificare gli stili della pagina senza dover ricorrere all'interfaccia del browser.
Il layout di partenza è costituito da un articolo presente sul sito dell'autore e disponibile in copia locale. Il layout si presenta come mostrato nella seguente immagine.
Figura 1: Il layout di partenza
[D]
Il layout di partenza appare strutturato nelle seguenti sezioni:
Il layout è impaginato su un'unica colonna, ossia è di tipo monolitico.
Il layout di partenza utilizza la seguente DTD:
La marcatura utilizzata nel corpo del documento è la seguente:
La marcatura è valida.
La struttura appena vista presenta alcuni vantaggi ed alcuni svantaggi.
Come si può notare, gli svantaggi superano i vantaggi.
Gli stili del layout di partenza sono i seguenti:
Ci soffermiamo solo su alcune caratteristiche interessanti:
body
sono stati impostati in em
(righe 7-8)h1
(riga 16)outline
) (riga 35)dt
vengono visualizzati come elementi di un elenco non ordinato, tramite i valori
list-item
della proprietà display
e square
della proprietà
list-style-type
(righe 72-73).Gli stili visti in precedenza presentano alcuni vantaggi ed alcuni svantaggi.
Come si può notare, gli svantaggi superano i vantaggi.
Per procedere alla trasformazione di questo layout dobbiamo operare su due livelli:
Poichè nel nostro layout di partenza i contenuti venivano all'ultimo posto, nel layout che vogliamo ottenere sposteremo i contenuti in avanti. Per fare questo, creeremo un layout a due colonne, inserendo il menu di navigazione ed il motore di ricerca nella colonna laterale, che verrà dopo i contenuti nel sorgente. Alla fine della pagina inseriremo un piè di pagina a chiusura del nostro layout.
Come abbiamo visto nel precedente seminario, per
abituarci ad una migliore correttezza formale, useremo la DTD
XHTML 1.1 e serviremo il nostro documento come application/xhtml+xml
. Parallelamente, osserveremo
i nostri progressi in un secondo documento servito come text/html
e avente lo stesso DOCTYPE del documento
originale di partenza. Si ricorda che per i file statici l'estensione dovrà essere .xht
o .xhtml
per il primo tipo ed .html
(e simili) per il secondo.
Quindi inizieremo il nostro nuovo documento scrivendo:
Usiamo la codifica UTF-8 per sfruttare al massimo la gamma di caratteri esistenti sul Web, avendo così a disposizione un insieme molto più vasto della tradizionale codifica ISO-8859-1. Questo ci permette di affrontare una futura internazionalizzazione delle nostre pagine con minore ansia.
La marcatura per il contenuto effettivo del nostro documento sarà quindi:
Possiamo verificare il lavoro svolto sinora nella versione XHTML e nella versione HTML del nostro documento.
Analizziamo in dettaglio la marcatura creata per il nuovo layout del documento.
#wrapper
per contenere l'intero layout della pagina#header
e dal suo figlio h1
#header
troviamo l'elemento #top
, che contiene:
#breadcrumbs
)#change-style
).#content
), al cui interno troviamo:
#gutter
), secondo una nota tecnica usata da Dan Cederholm nel suo recente
Bulletproof Webdesignh2
).code
che contiene il codice di esempio usato nell'articolo.#sidebar
), che contiene i seguenti elementi:
#navcontainer
)#nav
)address
, che reca il nome dell'autore del documento e funge
da piè di pagina.Alcuni punti sono interessanti:
il punto 3 è controverso, nel senso che attualmente si discute molto sull'opportunità di inserire le "briciole di pane" prima del contenuto effettivo della pagina. Quello che un lettore di schermo pronuncia è "Sei qui" e quindi i link. A nostro avviso far capire subito all'utente la sua posizione all'interno del sito è una buona scelta, in quanto lui/lei può rendersi meglio conto di dove si trova e tornare subito indietro in caso di errore o di ripensamento. Tuttavia, questa struttura ripetuta per l'intero sito può essere fastidiosa, specie se la profondità della struttura del sito aumenta e i link si moltiplicano. A livello di accessibilità la soluzione migliore può essere quella di inserire un link nascosto che punti subito ai contenuti e formattarlo come segue:
il posizionamento assoluto sfrutta in questo caso un valore negativo elevatissimo, che fa in modo che l'elemento scompaia dalla finestra di visualizzazione. Con questa tecnica, se vogliamo, è possibile nascondere un intero menu di navigazione ad uso dei software assistivi.
Si noti infine come da questa sezione siano stati rimossi i caratteri presentazionali, che saranno sostituiti dalla formattazione con i fogli di stile.
pre
per la formattazione dei blocchi di codice è sconsigliato in favore di un elenco ordinato opportunamente formattato.address
, spesso misconosciuto
o frainteso. L'elemento address
serve a fornire informazioni sull'autore del documento, ossia su chi ha
materialmente creato il documento e inserito i contenuti. Il suo scopo non è quindi quello di fornire informazioni
su chi ha commissionato il documento o sul proprietario del sito. Nel nostro caso, poiché il contenuto di tale elemento
fornisce il nome dell'autore del documento, la sua funzione di piè di pagina è perfettamente giustificata.Una volta ottenuta l'intelaiatura di base del documento, occorre cominciare a ragionare sugli stili da adottare. Riassumiamo quello che vogliamo ottenere:
Ragioniamo sul primo punto e poniamoci delle domande:
Domanda: Come posizionare gli elementi?
Risposta: Attualmente possiamo scegliere tra il float ed il posizionamento assoluto. Il posizionamento assoluto ha l'indubbio vantaggio di prescindere dall'ordine nel sorgente, ma ha anche il noto svantaggio di dipendere dalla quantità di contenuto presente sulla pagina, e questo diventa problematico nel caso di un sito dinamico. Il float dal canto suo dipende dall'ordine nel sorgente, ma è più flessibile rispetto al posizionamento assoluto. Volendo dare al nostro documento la maggiore applicabilità in àmbiti diversi, scegliamo di usare il float.
Domanda: Come ottenere la fluidità degli elementi sullo schermo?
Risposta: Scegliamo di usare misure in percentuale per gli elementi.
Domanda: Useremo immagini come sfondo degli elementi?
Risposta: Si, per il motivo elencato al punto 2.
Domanda: Applicheremo la fluidità anche ai font?
Risposta: Si, è indispensabile per ottenere un layout a misura di utente.
Domanda: Forniremo layout alternativi?
Risposta: Si, un layout a contrasto di colore invertito per gli utenti con problemi visivi.
Il secondo punto è più problematico, perché implica una riflessione quasi filosofica sul divario tra essere e apparire. Noi decidiamo di conciliare le due cose tenendo presente che:
Passiamo quindi a costruire il nostro layout seguendo un approccio top-down, ossia partendo dagli stili di base più generali fino ad arrivare a quelli delle specifiche sezioni del documento.
Immaginiamo di dover dipingere un quadro. Le prime due cose di cui dobbiamo occuparci sono i colori di base e le proporzioni del dipinto. Per i colori di base, dobbiamo solo assicurarci che il contrasto tra colore di sfondo e di primo piano soddisfi i requisiti del W3C. Per il resto, siamo liberi di assecondare la nostra fantasia. Per le proporzioni, invece, dobbiamo operare dei calcoli precisi per fare in modo che i contenuti trovino spazio sulla pagina. Spazio è la parola chiave. Il nostro layout fluido dovrà adattarsi alle varie risoluzioni di schermo senza mostrare sovrapposizioni di elementi o la comparsa della temuta barra di scorrimento orizzontale. Poiché useremo misure in percentuale, dobbiamo tenere presente che:
Qui entra in gioco il box model dei CSS e i calcoli che ne derivano. In breve:
i margini orizzontali, il padding orizzontale o i bordi destro e sinistro di un elemento si sommano alla larghezza espressa esplicitamente tramite la proprietà
width
. Per esempio, supponendo di avere i seguenti elementi di blocco:
Nei browser che rispettano il box model standard, l'elemento #child
fuoriuscirà dal suo genitore,
perché la seconda regola fa in modo che tale elemento occupi tutta la larghezza del suo genitore, più 2em complessivi
per il padding destro e sinistro.
Se lo scopo della seconda regola era quello di lasciare dello spazio tra i contenuti del box figlio e il suo genitore, allora si sarebbe potuto scrivere solo:
Così facendo il box figlio coinciderà ma non supererà il suo genitore,
in quanto la larghezza complessiva del blocco contenitore (l'elemento #box
) resterà inalterata
per la proprietà height
vale quanto detto per i calcoli della proprietà width
,
ma stavolta la somma va fatta tenendo presente i margini e il padding verticali e i bordi superiore ed inferiore.
Stabilite queste norme, dobbiamo decidere quale dimensione assegnare agli elementi della nostra pagina. Tenendo presente che si dovrebbe comunque garantire una certa leggibilità evitando una lunghezza di riga eccessiva, stabiliamo che:
Detto questo, passiamo a vedere in dettaglio il layout dei vari elementi.
Passiamo quindi ad esaminare gli stili generali che daremo al nostro layout.
Soffermiamoci sulle dichiarazioni date all'elemento body
:
abbiamo impostato un'immagine di sfondo ripetuta in verticale al fine di tracciare lo sfondo della colonna laterale, dando così l'impressione di una colonna che si estende per tutta l'altezza della pagina. Poichè la colonna ha una larghezza pari al 30% della larghezza complessiva della pagina, l'immagine di sfondo è stata posizionata lungo l'asse x ad una distanza pari al 70% della larghezza totale (100 - 70 = 30).
L'immagine è larga 2000 pixel ed è alta 10 pixel. Questa immagine è trasparente ad eccezione di un rettangolo a destra largo 600 pixel e riempito con un colore di sfondo azzurro chiaro ed un bordo sinistro blu scuro. La larghezza del rettangolo colorato deve essere pari al 30% della larghezza complessiva dell'immagine (2000 pixel). Le dimensioni dell'immagine sono tali da permettere allo sfondo di adattarsi anche a risoluzioni di schermo molto elevate.
Abbiamo avuto cura di impostare anche un colore di sfondo per l'elemento body
, in modo da permettere la lettura
qualora l'immagine di sfondo non fosse reperibile.
A questo punto occorre evidenziare un'importante differenza esistente tra il nostro documento servito come application/xhtml+xml
e lo stesso documento servito come text/html
. La differenza viene riassunta
nelle due immagini che seguono.
Figure 2-3: L'immagine di sfondo in HTML (a sinistra) e in XHTML (a destra)
[D]
Nella prima figura abbiamo il documento servito come text/html
. In questo caso l'elemento body
viene
trattato in modo speciale dai browser, nel senso che questo elemento copre interamente lo sfondo dell'elemento html
, ossia
dell'elemento radice. In altre parole, body
"ruba" lo sfondo dell'elemento radice.
Nella seconda figura abbiamo il documento servito come application/xhtml+xml
. In questo caso lo spazio bianco è
giustificato dal fatto che ora body
viene considerato come un elemento qualsiasi, ed il "furto" dello sfondo
non ha più luogo. Poichè l'elemento h1
ha dei margini verticali, i browser ritengono che si venga a creare
dello spazio tra l'elemento radice e body
. Tale spazio viene mostrato.
Come ovviare al problema? La soluzione più semplice è quella di specificare l'immagine di sfondo anche per l'elemento
html
, usando la stessa dichiarazione usata per l'elemento body
. Nel nostro caso questa soluzione
non è necessaria, perché quello spazio sarà colmato dall'intestazione del nostro layout.
Possiamo osservare il lavoro svolto sinora nel nostro documento XHTML e nel nostro documento HTML.
Gli stili del contenitore generale sono i seguenti:
La larghezza del contenitore generale è ora pari al 100% della finestra di visualizzazione. La dimensione dei font è stata qui ridotta del 10%. A questo proposito occorre citare la riflessione di Franco Frascolla in merito alla necessità che la dimensione dei font non sia inferiore al 100%/1em. Questa riflessione in generale è valida, ma occorre fare alcune precisazioni in sede di design:
La dimensione del contenitore del testo nel layout originale era tale da consentire l'uso del valore 100%/1em. Nel nostro caso la colonna dei contenuti avrà una dimensione pari al 70% della finestra di visualizzazione. In questo caso la scelta di ridurre il font ci appare ragionevole, tenendo anche presente che:
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Passiamo quindi ad assegnare le regole di stile all'intestazione del nostro documento:
Passiamo in rassegna i nostri stili:
body
. L'immagine di sfondo è allineata in alto a sinistra (coordinate 0, 0) e non viene ripetuta. La larghezza
dell'elemento #header
coincide con quella della finestra di visualizzazione. Abbiamo applicato anche un bordo
inferioreh1
. Azzeriamo i margini dell'elemento e gli assegniamo un'immagine di sfondo posta alla sua destra e centrata
in verticale (coordinate 100%, 50%). Il colore di sfondo del titolo è trasparente, in modo da non coprire lo sfondo
del suo genitore.Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Tocca ora alla sezione "Sei qui" e allo style switcher. Decidiamo di raggrupparli all'interno di un unico elemento e di farli apparire l'uno a sinistra e l'altro a destra. Gli stili saranno:
Vediamo in dettaglio i nostri stili:
#top
va a contenere le sezioni "Sei qui" e lo style
switcher. Abbiamo impostato un'altezza uguale all'interlinea per 1) contenere i float che andremo ad usare (valore proprietà
height
) e 2) centrare il testo in verticale all'interno degli elementi (valore proprietà
line-height
= valore proprietà height
). Grazie a questa dichiarazione, la semiinterlinea
sarà uguale a 0.7em sopra e sotto il testo, il quale verrà centrato in verticale#breadcrumbs
a sinistra, ma non ne impostiamo la
larghezza, in modo che in questo caso venga applicato l'algoritmo shrink-to-fit. Tale algoritmo fa in modo che
la larghezza del float sia sufficiente per ospitare il suo contenuto, avendo così un float che si adatta al suo contenuto.
Si noti che abbiamo ripetuto le dichiarazioni di altezza e di interlinea impostate in precedenza. Anche le voci dell'elenco sono
state flottate a sinistra, e anche per loro abbiamo la stessa altezza e la stessa interlinea, più un padding destro
per distanziare le vociPossiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Passiamo quindi a dare i primi stili ai contenuti:
L'elemento #content
è stato fatto flottare a sinistra e gli è stata assegnata una
larghezza pari al 70% della superficie di visualizzazione. Abbiamo annullato i suoi margini per evitare che i browser
assegnino dei valori extra al momento del floating. L'elemento #gutter
funge da spaziatore tra i contenuti
e la colonna laterale, tramite un padding destro pari ad 1em. Il padding superiore (1em) serve ad evitare problemi
nel computo dei margini verticali tra tale elemento e i suoi figli di blocco.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Formattiamo quindi le intestazioni e i paragrafi all'interno dei contenuti:
Il titolo dell'articolo ha un font Arial Narrow di colore rosso scuro con una dimensione pari ad 1.6em. La sua interlinea è stata normalizzata in modo da evitare che ci crei spazio tra il testo ed il bordo sottostante. L'elemento ha un'immagine di sfondo posta alla sua sinistra e centrata in verticale (coordinate 0 50%). L'indentazione serve a creare dello spazio tra l'immagine ed il testo del titolo. I paragrafi usano il solo padding verticale, al fine di evitare alcuni problemi inerenti al computo dei margini verticali collassati.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Passiamo quindi alla formattazione dei blocchi di codice, ricordando che abbiamo scelto di usare un elenco
ordinato in luogo dell'elemento pre
, in quanto:
All'interno delle voci dell'elenco useremo l'elemento code
, che è sicuramente più
indicato a livello semantico. Gli stili sono i seguenti:
.code
. Il suo rientro viene annullato,
gli viene assegnato un padding su tutti i lati ed un bordolist-style: none
. Per rendere lo stile compatibile anche con Internet Explorer
7 ed inferiori si imposta il colore di sfondo sullo stesso valore del colore del testo, eliminando la visualizzazione
del marcatore. Questa dichiarazione viene poi sovrascritta sull'elemento code
(righe 14-16).indent1
) e
l'eventuale spazio verticale tra le righe del codice (classe .vspace
). Si noti che per l'indentazione si può
usare anche un padding sinistro, particolarmente indicato se una riga di codice viene spezzata su due righe.Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Passiamo quindi a posizionare a destra la colonna laterale:
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Diamo quindi i primi stili al nostro menu di navigazione:
Centriamo il contenitore esterno del menu di navigazione (#navcontainer
) tramite margini orizzontali
automatici e gli assegniamo una larghezza pari al 90% della colonna laterale. Quindi posizioniamo un'immagine di sfondo
in alto a sinistra. Questa immagine andrà a formare l'angolo arrotondato superiore del menu.
A questo punto passiamo all'elenco non ordinato (#nav
). Annulliamo i suoi margini e il suo padding e gli assegniamo
un larghezza pari a quella del suo genitore. Quindi posizioniamo un'immagine di sfondo sulla parte inferiore destra dell'elemento.
Questa immagine andrà a formare l'angolo arrotondato inferiore del menu. Si noti come il colore di sfondo di questo
elemento sia trasparente, in modo da non coprire l'immagine di sfondo del suo genitore.
La centratura orizzontale tramite margini automatici non è compatibile con Internet Explorer 5. A questo proposito dovremmo:
text-align: center
sull'elemento #navcontainer
text-align: left
sull'elemento #nav
.Si noti infine come le dichiarazioni di larghezza siano sempre esplicite. Questo ci permette di evitare i noti problemi con alcune versioni di Internet Explorer.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Il menu di navigazione che andremo a formattare è un menu verticale a blocchi. Scegliamo di usare un indicatore per la sezione corrente ed un rollover per i link attivi. Gli stili saranno:
strong
svolge qui la funzione di marcare la sezione corrente.
Viene quindi reso di blocco e gli viene assegnata una particolare immagine di sfondo posta a sinistra e centrata in verticale
(coordinate 0, 50%). Il testo viene reso in maiuscolo ed indentato di 1.5emstrong
. Sullo stato :hover
viene modificato il colore di sfondo ed assegnata
un'immagine di sfondo posta a sinistra e centrata in verticale.Si noti la ridondanza di dichiarazioni relative alla larghezza degli elementi, necessarie per evitare problemi in Internet Explorer 6 ed inferiori. Si noti anche come si sia evitato il preload delle immagini sul rollover, dato il peso irrisorio di queste ultime (pochi bytes).
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Il motore di ricerca presenta i seguenti stili:
Come il menu di navigazione, il modulo viene centrato in orizzontale tramite i margini automatici e gli viene asssegnata la stessa larghezza del menu. I margini verticali del modulo e del paragrafo al suo interno vengono azzerati, onde evitare i noti problemi di Internet Explorer 6 nel computo dei margini degli elementi dei moduli. Poiché abbiamo assegnato due ID differenti al campo di testo e al bottone di invio, essi ricevono due stili diversi. Il primo ha una larghezza pari al 50% della larghezza del modulo ed un bordo nero, mentre il secondo ha il testo in grassetto. Poiché un fattore fondamentale nel computo delle dimensioni degli elementi dei moduli è costituito dal tipo di font scelto e dalla sua dimensione, impostiamo lo stesso tipo di font e la stessa dimensione per tali elementi. Ricordiamo che attualmente i browser applicano l'ereditarietà in modo diverso sugli elementi dei moduli. Si rende quindi necessario specificare il tipo e la dimensione del font su ogni elemento.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Infine, posizioniamo il piè di pagina sotto i contenuti e la colonna laterale, assegnandogli i seguenti stili:
La prima dichiarazione riguarda la proprietà clear
e serve a ripristinare il flusso normale
del documento dopo i float. Poiché gli elementi sono flottati in entrambe le direzioni usiamo qui il valore
both
. I margini verticali dell'elemento vengono annullati, poiché il computo di tali margini
con la proprietà clear
sono diversi da browser a browser. Assegniamo una larghezza esplicita all'elemento
per evitare alcuni problemi con Internet Explorer 6 ed inferiori. Centriamo quindi il testo in orizzontale ed in verticale, assegnandogli una dimensione superiore al normale. Per centrare il testo in verticale abbiamo usato la stessa tecnica
vista in precedenza per la sezione "Sei qui". Poiché l'elemento avrà un'immagine di sfondo posizionata
in basso a destra (coordinate 100%, 50%), la sua altezza dovrà essere proporzionale alle dimensioni dell'immagine.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Il codice JavaScript dello style switcher è tratto dall'articolo presente all'indirizzo http://www.alistapart.com/articles/alternate. La soluzione JavaScript è da considerarsi come un ripiego se non si ha la possibilità di usare un più sicuro codice lato server, come PHP (si veda in tal senso quanto scritto da Gianluca Troiani in CSS. Guida completa o si vada all'indirizzo http://css-discuss.incutio.com/?page=StyleSwitching).
Nello specifico, il codice JavaScript compie le seguenti operazioni:
link
presenti nel documentoif
Occorre quindi modificare la nostra marcatura come segue:
Nel corpo del documento apporteremo le seguenti modifiche:
Alcuni autori associano anche il metodo location.reload()
al precedente codice. Se ne sconsiglia l'uso in quanto
aggiungerebbe un inutile refresh alla pagina.
Possiamo osservare i nostri progressi nel nostro documento XHTML e nel nostro documento HTML.
Il layout accessibile usato nel nostro esempio si rivolge soprattutto alle persone ipovedenti e a quegli utenti che possono trarre beneficio da un contrasto di colori invertito. Nello specifico, esso presenta le seguenti caratteristiche:
La struttura a due colonne è stata mantenuta, anche se si può linearizzare completamente la pagina eliminando le dichiarazioni di floating o di posizionamento. Nel nostro caso, poiché la struttura principale di navigazione è stata posta dopo i contenuti, si è preferito evitare all'utente il fastidio di dover scrollare l'intera pagina per accedere a tali informazioni. In ogni caso, si può sempre nascondere un menu di navigazione ad hoc e visualizzarlo solo nel layout alternativo.
Uno stile così concepito può anche essere usato come foglio di stile utente. In questo caso occorrerà
usare la dichiarazione !important
per sovrascrivere il foglio di stile dell'autore e del browser. Esempio:
Alla fine del nostro percorso, abbiamo migliorato un layout scadente portandolo verso un quasi livello di accettabilità. Restano tuttavia dei dubbi sulla reale accessibilità, usabilità e tassonomia informativa del documento. Questi dubbi potranno essere fugati solo con un dialogo aperto con esperti dei rispettivi settori, fermo restando il principio di mettere al servizio degli utenti le tecniche esposte sinora.