In questo articolo affronteremo un argomento complesso e affascinante: la realizzazione del layout di un sito solo con i CSS. La sfida è sempre la stessa: arrivare alla separazione tra stile, layout e struttura dei contenuti per ottenere pagine più semplici da gestire, più veloci da caricare, più accessibili, aderenti agli standard del W3C.
Si tratta, allo stesso tempo, di fare i conti con un ambito di applicazione dei CSS ancora poco sfruttato ma molto promettente. Se nella gestione della tipografia e delle proprietà dei blocchi di testo l'adozione dei fogli di stile è ormai cosa stabile e accettata, per la costruzione del layout generale di un pagina siamo ancora lontani da una diffusione che esca dai limiti, a volte davvero pregevoli, di siti personali e/o sperimentali. Eppure il mercato dei browser è oggi propizio e ci sono davvero le condizioni per fare il salto. In verità il cambiamento richiede un cambio di approccio notevole e la ridefinizione di metodi di lavoro ormai consolidati: tempo al tempo dunque.
Ancora una riflessione: l'adozione dei CCS per il layout ha visto spesso come unico slogan di accompagnamento "Morte alle tabelle!". Che è giusto, ma che mette in secondo piano altri e più importanti vantaggi: codice più pulito, facilità di gestione, migliore accessibilità, portabilità dei documenti. Ma volete mettere? Se io dico: "Questa pagina è fatta senza tabelle", troverò sempre qualcuno disposto a dirmi: "Davvero?! E come si fa?". Facciamo una prova.
Ecco il piccolo esperimento che vi propongo. Seguite questo link. È la pagina principale (incompleta, ma rende l'idea) della sezione PRO HTML.it.
È fatta senza usare tabelle, solo con i CSS. Anche i rollover e gli pseudopulsanti della barra sinistra sono fatti con i CSS (niente Javascript, niente immagini). Funziona in tutti i browser con un supporto decente degli standard (diciamo dalla versione 5 in su). Ora provate a visualizzare e confrontare il markup di questa pagina e dell'originale. Le conclusioni le lascio a voi.
Il modo in cui la pagina è stata convertita sarà l'argomento conclusivo di questa serie di lezioni. Prima analizzeremo con un approccio molto concreto altri tipi classici di layout: a due e tre colonne. Vedremo inoltre come sia possibile ottenere layout "appoggiati a sinistra", centrati o "liquidi" (quelli che occupano l'intera area della finestra a qualunque risoluzione). Un utile confronto sarà quello con Come impostare un sito ridimensionabile di questa sezione, dove vengono spiegate le tecniche per ottenere gli stessi risultati con le tabelle.
Prerequisiti
L'argomento, come dicevamo, è complesso. Richiede pertanto una conoscenza di elementi anche avanzati dei CSS. La lista dei prerequisiti tecnici per affrontare con costrutto le lezioni e passare quindi alla pratica e alla sperimentazione breve. Saranno solo cenni, in quanto argomenti già presenti in altre sezioni del sito. In fondo all'articolo trovate poi una serie di link a risorse sul web: vi consiglio di visitarli perchè rappresentano spesso documenti davvero impareggiabili. Ecco cosa è importante conoscere:
1. Regole di base di (X)HTML e CSS
2. Il "box model"
Ovvero: sapere come ciascuno dei blocchi che formano un pagina può essere impostato secondo le sue principali proprietà: larghezza e altezza, margini e bordi, padding e colori di sfondo.
L'articolo Alleggerire le pagine di dati con i CSS contiene un utile spiegazione (con figure esplicative) dei concetti fondamentali.
3. La proprietà float
Il floating è un altro modo per definire la posizione di un elemento. Cosa succede quando applico questa proprietà? Semplificando: l'elemento viene rimosso dal normale flusso dei dati e viene portato all'estremità sinistra (o destra) del suo box contenitore. Il testo eventualmente presente fuori dall'elemento scorre intorno ad esso. Gli esempi commentati chiariranno meglio il concetto.
4. Il posizionamento
Se si vuole realizzare un layout perfetto non si possono ignorare le regole di base del posizionamento. La Le pseudo-classi di HTML.it fornisce al riguardo ottime indicazioni sui concetti di base. Troverete la spiegazione sui vari tipi di posizionamento e una serie di utilissimi esempi pratici.
Siti di riferimento
Da quando la costruzione di layout con i CSS è diventata una cosa realizzabile senza grossi traumi (con l'avvento della quinta generazione di browser) è partita una sorta di sfida alla ricerca di soluzioni ottimali. Alcuni siti si sono contraddistinti nella promozione dell'idea e nella diffusione di supporto, template e discussioni tecniche. Vi ricordo i più importanti. Segnateli tra i preferiti. Se siete seriamente interesasti all'argomento non potete non visitarli e studiarli a fondo: si può davvero dire che la stragrande maggioranza dei layout non tabellari ha preso lo spunto da uno di questi.
- A list apart:
sulla webzine di Jeffrey Zeldman l'argomento è stato presentato con
enfasi in un articolo pionieristico: From
Hacks to Standards: A Web Designer's Journey. Alcun soluzioni sono
superate, anche per via dell'avvento di nuovi browser, ma spirito e tono dell'articolo
sono quelli della scoperta. Da leggere - Glish CSS: Glish è il sito curato da Eric Costello e inizia la serie dei siti-risorsa. La cosa
più importante, oltre a due o tre articoli tecnici, è la raccolta di layout con CSS. Codice commentato, esempi, template pronti per l'uso. Ecellente. - Box Lessons: il titolo parla da sè. Si tratta dei tutorial sui layout non tabellari di Owen Briggs. Anche qui potete trovare una serie nutrita di template commentati e spiegati.
- Layout Reservoir: pochi i template presentati, ma qualità, eleganza e funzionalità sono di prima scelta.
- CSS/Edge:
il sito degli esperimenti di Eric Meyer. Di quest'ultimo è
appena uscito in America un meraviglioso libro: Eric
Meyer on CSS. Tredici progetti avanzati spiegati e analizzati nei dettagli.
Il codice degli esempi è reperibile sul sito di accompagnamento del
libro.
Un cambiamento di approccio
Passare da un layout tabellare all'uso dei CSS richiede alcuni cambiamenti di approccio nella concezione e nella realizzazione delle pagine. Innanzitutto, imparate a suddividere concettualmente ogni pagina in sezioni. Esercitatevi con un tipo di analisi simile a quella proposta in questo esempio. Insomma: non vedete nella pagina che state progettando un insieme di celle e colonne, ma una struttura organizzata di sezioni e blocchi di contenuto. In (X)HTML ogni sezione sarà contrassegnata da un tag <div> le cui proprietà visuali vanno impostate in un CSS.
Dimenticate approcci tipo: "Apro Dreamweaver e faccio un sito". Gli editor visuali hanno un supporto scadente dei layout CSS (con l'eccezione del nuovo Dreamweaver MX). Significa che dovrete rinunciare alle comodità dell'editing istantaneo e senza vedere codice. Ciò può causare qualche frustrazione iniziale, ma se siete supportati da buone conoscenze e chiarezza di idee vedrete che la costruzione dell'HTML sarà ancora più semplice di prima.
Un layout fluido e ridimensionabile
Bene, è il momento della pratica. Ho deciso di evitare lunghe introduzioni
su argomenti teorici. Affronteremo i problemi quando verranno alla luce.
Iniziamo la nostra carrellata da un semplicissimo layout fluido a due colonne con testata superiore. Questa è la struttura che realizzeremo. Il modello è dei più tradizionali. Una sezione superiore estesa in larghezza, una barra di menu a sinistra, una sezione di contenuto nella parte destra. Ciascuna delle tre sezioni sarà un div nel documento (X)HTML.
Per costruire un layout fluido e ridimensionabile sarà sufficiente impostare una larghezza fissa per la sezione dei menu, lasciando che la parte dei contenuti e la testata superiore si adattino automaticamente alla dimensione dello schermo. Un problema da risolvere sarà quello dell'altezza della sezione dei menu, che dovrà espandersi automaticamente in base a quella della sezione contenuti.
Ecco l'esempio realizzato (nella parte centrale trovate il codice completo). Osservate innanzitutto che si tratta di un documento XHTML 1.0 aderente alla DTD Transitional. Il codice è semplice e pulito. Se pensate che gli stili potevano essere piazzati in un foglio esterno capite bene che bastano poche righe. Vediamo come abbiamo proceduto alla creazione del layout analizzando
il CSS.
L'elemento BODY
body {
margin:0px;
padding:0px;
background-color:#CCCCCC;
height: 100%;
}
Iniziamo impostando le proprietà dell'elemento body. Il margine e il padding vanno settati a 0px per eliminare lo spazio bianco che ogni browser aggiunge, in misura variabile, tra i bordi della finestra principale (il cosiddetto viewport) e l'area del contenuto. Stabiliamo che il colore di sfondo sarà un grigio chiaro e settiamo quindi la proprietà height al 100%. Vedremo poi perchè è necessario impostare questo valore.
Subito dopo (vedi codice) impostiamo le proprietà per i titoli principali (h1) e per i paragrafi (p).
La testata della pagina
#testata {
margin:0px;
padding:0px;
height:70px;
background-color:#000099;
background-image: url(sfondo.gif);
}
Da qui inizia la definizione delle tre sezioni principali. Si creano tre selettori di tipo id (ricordiamo che la dichiarazione inizia con il simbolo #) e se ne definiscono le proprietà.
La testata dovrà occupare per intero la larghezza della finestra, pertanto non stabiliamo nessun valore per width. Così facendo la larghezza sarà automaticamente quella dell'elemento parente. Complicato? Solo se non si ha chiaro un concetto: ogni documento HTML può essere visto come un albero, con un elemento radice e con una serie di altri elementi che possono avere tra di loro rapporti del tipo parente - figlio. Ecco come si potrebbe visualizzare la struttura semplicissima del nostro documento:
Per il div #testata, visto che l'elemento parente è body, la larghezza sarà sempre uguale a quella di quest'ultimo elemento. In pratica, usate width solo quando volete specificare una misura e ricordate che la larghezza massima di un elemento non può essere superiore a quella dell'elemento parente. Ecco cosa succede se si imposta la larghezza di body a 600px (visualizza l'esempio). Anche la larghezza della testata si adatterà a questo valore.
Con height stabiliamo invece l'altezza, che sarà di 70px. Seguono le impostazioni del colore e dell'immagine di sfondo.
I menu
#menu {
width:180px;
position:absolute;
top:70px;
left:0px;
background-color:#CCCCCC;
height: 100%;
}
La sezione dei menu la mettiamo a sinistra. Il div avrà una larghezza fissa: con qualunque risoluzione occuperà lo spazio di 180px. Ovviamente si poteva impostare il valore di width anche in percentuale: in questo caso avremo un layout totalmente fluido e ridimensionabile (visualizza l'esempio, width=20%). La larghezza espressa in percentuale è sempre relativa a quella dell'elemento parente. Anche per questo div l'elemento parente è body.
La parte successiva della dichiarazione stabilisce in quale punto della pagina verrà visualizzato il div. Il posizionamento scelto è di tipo assoluto: l'elemento è completamente eliminato dal flusso dei dati e verrà visualizzato in una posizione dettata dalle coordinate left e top rispetto all'elemento parente (o blocco contenitore). La barra dei menu sarà dunque posizionata a 0px dal bordo sinistro e a 70px da quello superiore della finestra del documento. Perchè impostiamo 70px è facile da capire: è l'altezza della testata: scegliendo una misura inferiore il div #menu si sarebbe sovrapposto alla testata stessa.
La regola da ricavare e imparare è dunque questa: un elemento posizionato in modo assoluto sarà sempre posizionato rispetto al suo blocco contenitore. Esso è costituito da qualunque elemento che abbia un tipo di posizionamento diverso da static. Se un elemento così configurato non esiste allora il blocco contenitore è l'elemento radice del documento, <html> (ricordatelo, l'elemento radice è <html> e non <body>!). Alla fine, dal punto di vista visuale le cose non cambiano molto: l'elemento <html> definisce la finestra centrale del browser, dove trovano posto i contenuti del documento.
Torniamo a noi. Il posizionamento del div #menu avverrà in base ad <html>, in quanto esso non ha elementi parenti con posizione non statica.
L'altezza del div è settata al 100%. Anche qui è necessario un chiarimento. L'altezza di un elemento è in genere basata sul suo contenuto. In pratica, se non avessi stabilito alcun valore per height avrei avuto questa situazione (visualizza l'esempio). Ma io voglio che la mia barra si estenda per quanto si estende in altezza la pagina! Basta scrivere height: 100%? Non proprio, perchè la percentuale (ormai lo sappiamo) fa sempre riferimento all'elemento parente. Ecco perchè prima abbiamo impostato l'altezza per <body>! In questo modo il div "menu" avrà una dimensione cui riferirsi e la sua altezza sarà sempre uguale, a prescindere dal contenuto, a quella di <body>.
Tutto risolto? Ancora no. In realtà, i browser identificano come altezza di <body> quella della parte visibile della finestra centrale del browser. Ecco che situazione avremmo avuto (visualizza l'esempio). Per ottenere il risultato desiderato è sufficiente impostare lo stesso colore di sfondo per il menu e per <body>, come nell'esempio iniziale). Semplice no?
I Contenuti
#contenuto {
margin:0px 0px 0px 180px;
padding:10px;
background-color: #FFFFFF;
}
L'ultima sezione è quella per i contenuti principali della pagina. In una prospettiva di layout liquido e con un div a larghezza fissa (#menu), sarà proprio essa che dovrà adattare le proprie dimensioni a quelle della finestra. Come potete vedere non ricorriamo ad alcun tipo di posizionamento particolare, nè specifichiamo la larghezza. Usiamo semplicemente i margini. Dove andrà collocarsi il nostro div? I valori della proprietà margin sono 4. Ricordiamo che l'ordine di lettura è sempre questo: TOP - RIGHT - BOTTOM - LEFT. Se vogliamo che il div "contenuto" non si sovrapponga alla barra dei menu dovremo impostare un margine sinistro che sia almeno uguale alla larghezza di quest'ultimo (180px). Per il resto i valori sono di 0px: il div sarà così adiacente, sugli altri tre lati, agli elementi vicini.
Bene, come vedete non è così difficile. In pochi passi abbiamo ottenuto un layout senza tabelle e un documento XHTML valido. L'importante è imparare le tecniche di base. Quelle viste in questa prima lezione riguardano:
- l'uso della larghezza automatica
- il posizionamento assoluto
- l'altezza degli elementi
- l'uso dei margini come strumento di posizionamento
Riferimenti
Le guide di HTML.it possono sempre essere il vostro punto di riferimento. In particolare vi segnalo la guida ai CSS e la guida XHTML, la cui seconda parte affronta in forma di tutorial la creazione di un semplice layout non tabellare.
- Tutorial sul posizionamento 1 - Eccellente tutorial sulle regole del posizionamento dinamico con esempi e spieagazioni esaustive.
- Tutorial sul posizionamento 2 - Dal sito Web Reference un'altra grande risorsa sullo stesso argomento. Da leggere e conservare!
- Uso del floating - Ancora un ottimo tutorial da Web Reference.
- Il box model spiegato dal W3C
- Il box model: teoria e pratica - Se i tecnicismi del W3C vi spaventano troverete in questo tutorial in due parti le risposte che cercate su questo fondamentale argomento.
Nella prima parte abbiamo visto come con poche righe di codice sia posibile ottenere un semplice layout liquido a due colonne con testata. Facciamo un piccolo passo avanti aggiungendo alla nostra costruzione una seconda colonna dei menu posizionata a destra: è forse il layout più diffuso, davvero un classico. Nella seconda parte affronteremo alcune importanti questioni di compatibilità e resa visiva tra i browser.
Un semplice layout a 3 colonne
La struttura da realizzare è questa. Come al solito, ad ogni sezione corrisponde un div nella struttura XHTML e un selettore di tipo id nel CSS. Schematizzando:
- Testata = #testata
- Menu sinistro = #menusin
- Menu destro = #menudes
- Contenuto = #contenuto
Il metodo è sostanzialmente identico a quello del layout a due colonne. Procediamo con ordine, tenendo presente l'esempio realizzato e il codice.
body {
margin:0px;
padding:0px;
font-family:verdana, arial, helvetica, sans-serif;
color:#333;
background-color:#CCCCCC;
height: 100%;
}
Le impostazioni per l'elemento body sono invariate, compresa la proprietà height settata al 100% per risolvere il problema dell'altezza dei menu laterali.
#testata {
margin:0px;
padding:0px;
height:70px;
background-color:#000099;
background-image: url(sfondo.gif);
}
#menusin {
position:absolute;
top:70px;
left:0px;
width:180px;
background-color:#CCCCCC;
height: 100%;
}
Anche per la testata e il menu sinistro rimangono le stesse impostazioni: larghezza fissa (180px) e posizionamento assoluto per il menu, altezza fissa a 70px per la testata. A questo proposito: se usate un banner o un'immagine-logo per questa sezione, prendete nota delle dimensioni verticali e usatele come riferimento per l'altezza del div.
#menudes {
position:absolute;
top:70px;
right:0px;
width:150px;
background-color:#CCCCCC;
height: 100%;
}
Ecco la prima novità. Con #menudes definiamo la barra dei menu laterale destra. Ricordiamo il concetto espresso nel primo tutorial: per avere un layout ridimensionabile impostiamo le colonne laterali a larghezza fissa e quella centrale a larghezza automatica.
Dunque, il menu destro avrà una larghezza di 150px. Il posizionamento avverrà questa volta in base alle coordinate top (70px) e right (0px): il div sarà così appoggiato al margine destro della finestra del browser e a 70px in basso rispetto a quello superiore (subito dopo la testata). Come per #menusin impostiamo l'altezza al 100% e il colore di sfondo come quello del corpo pagina (vedi articolo precedente).
#contenuto {
margin:0px 150px 0px 180px;
padding:10px;
background-color: #FFFFFF;
}
Ed ecco l'ultima sezione. Anche qui larghezza automatica (non impostare alcun valore equivale a scrivere width : auto;) e gioco sui margini. Questa volta andrà impostato ad una distanza almeno equivalente alla larghezza dei menu, anche il valore del margine destro. Schematizzando:
- #menusin: width 180px = #contenuto: margine sinistro 180 px
- #menudes: width 150px = #contenuto: margine destro 150 px
Ora uno sguardo al codice XHTML. Osservate l'ordine con cui ho inserito le sezioni:
- #testata
- #menusin
- #menudes
- #contenuto
Rispetto al normale flusso dei dati #menudes dovrebbe comparire dopo il menu sinistro. Ma così non è. Quando uso un div con posizionamento assoluto, esso può comparire in qualunque punto del documento: la sua posizione è fissata nel CSS e non è influenzata da quella che occupa nel flusso dei dati.
Bene, abbiamo imparato le basi esercitandoci su tipi di layout molto tradizionali. Abbiamo soprattutto fatto un'opera di trasposizione di semplici strutture tabellari. Non fermatevi qui. L'approccio non deve essere: "Come faccio con i CSS quello che facevo con le tabelle". Usate questo metodo come pura esercitazione. Per il resto esplorate nuove strade, esercitate la vostra creatività.
Prima o poi incontrerete ovviamente problemi, il primo, che andremo subito ad affrontare, si chiama compatibilità tra i browser.
Questioni di compatibilità
Stando alle dichiarazioni dei maggiori produttori, tutti i browser recenti hanno un supporto completo di CSS1, mentre ancora parziale per alcuni è quello di CSS2. Vero.
Il panorama è certamente più roseo di qualche anno fa. Ma state certi che i problemi non sono finiti. Rimarrà sempre un dettaglio, una piccola cosa che un browser renderà in modo diverso dall'altro. Non preoccupatevi. I maestri ci insegnano che il web non è la carta e l'assoluta identità di visualizzazione su piattaforme diverse è al tempo stesso un mito e un ostacolo spesso frustrante. Se volete un design con assoluta e universale precisione al millesimo di pixel c'è un programma che fa per voi: si chiama Flash.
Torniamo a noi. Se finora è andato tutto liscio è perchè ci siamo limitati a layout molto di base, senza fronzoli, ma funzionali e funzionanti in tutti i browser con supporto degli standard. Per esempio, non abbiamo fatto un uso spinto di bordi, margini e padding.
Vi propongo ora il modello di layout a tre colonne reperibile sul sito CSS Layout Reservoir (modificato solo in alcune parti per chiarezza).
Studiando il codice e osservando la pagina noterete che il metodo per ottenere una pagina fluida è lo stesso da noi utilizzato: due menu laterali a larghezza fissa e una sezione centrale ridimensionabile posizionata con i margini. La differenza sta nel fatto che i vari DIV presentano un bordo esterno, un padding e sono separati da margini: una struttura complessivamente più ariosa ed elegante. Questo tipo di situazione ci consente di affrontare un serio problema di interpretazione dei CSS che affligge quello che è ancora oggi il browser più diffuso: Internet Explorer 5.x per Windows.
All'uscita della versione 6, Microsoft ha pubblicato sulla sua MSDN un
lungo articolo per illustrarne le migliorie nell'implementazione dei CSS.
Il punto fondamentale è che Explorer 6 interpreta ora correttamente il
box model. Spieghiamo.
Secondo le specifiche del W3C larghezza effettiva di un box è data dalla seguente operazione:
bordo sinistro + padding sinistro + width + padding destro + bordo destro
In pratica, se ho un box con queste proprietà:
#box1 {
border: 20px solid black;
padding: 20px;
width: 300px;
}
esso avrà come larghezza effettiva, sullo schermo, 20 + 20 + 300 + 20 + 20 = 380px (visualizza l'esempio). Da qui ricaviamo che la proprietà width si riferisce sempre all'area del contenuto di un box.
Explorer 5.x invece interpreta width come la larghezza complessiva, compresi bordi e padding. L'area del contenuto, dunque, sarà di soli 220px (300-20-20-20-20 = 220px).
Come si vede dall'esempio una bella differenza. Ciò comporta che quando si usa width accompagnata dalla definizione di bordi o padding bisogna sempre tenere presente questa situazione. Le soluzioni possibili sono due:
- non usare bordi e padding sui DIV principali (quella che abbiamo adottato nei primi esempi)
- usare il trucchetto di Tantek Celik
Vediamolo subito.
Tantek Celik è impegnato nel team di sviluppo di Explore per Mac ed è davvero un'autorità in materia. Il suo trucchetto per risolvere il problema di Explorer 5.x si basa su un bug dello stesso browser ed è applicato all'ultimo layout analizzato. Esaminiamo il codice per spiegarlo:
#menusin {
position:absolute;
width:150px;
top:110px;
left:20px;
border:1px dashed black;
background-color:#eee;
padding:10px;
/* Questo è il trucco per ingannare Explorer 5 */
voice-family: ""}"";
voice-family:inherit;
width:128px;
}
/* Con questa dichiarazione risolviamo un bug di Opera 5 */
body#menusin {width:128px;}
Ciò che vogliamo ottenere è un box che sia largo complessivamente 150px e con un area del contenuto di 128px. Nella prima parte (fino alla dichiarazione del padding) lavoriamo per Explorer 5.x:
150 (width, ma per lui la larghezza complessiva) - 1 - 10 - 10 - 1 = 128px
A questo punto si inseriscono queste due dichiarazioni che interrompono, per un bug, l'elaborazione del codice nel browser:
voice-family: ""}"";
voice-family:inherit;
Ora possiamo inserire il valore di 128px di larghezza che sarà interpretato solo dai browser corretti e che si sovrappone a quello di 150px. Il risultato sarà dunque:
128 + 1 + 10 + 10 + 1 = 150px.
Con l'ultima dichiarazione risolviamo un effetto collaterale in Opera 5.
Insomma, se volete lavorare con precisione dovrete fare un pò di calcoli e tutto andrà bene. D'altro canto, se Netscape 4 lo possiamo ormai mettere da parte, sarebbe folle non curarsi di Explorer 5.x. Approfondimenti li trovate nei siti di riferimento citati nell'articolo precedente.
Il giusto DOCTYPE
Il nostro obiettivo in questi articoli non è solo quello di avere layout con i CSS, ma di costruire documenti aderenti agli standard e validi. Ora, per validare un documento, HTML o XHTML, esso deve avere all'inizio la dichiarazione del DOCTYPE.
È importante sapere che browser recenti come Explorer 6 Win, Explorer 5 Mac e quelli basati su Gecko, adottano un meccanismo di switching proprio in base al DOCTYPE. In pratica, se non si inserisce quello giusto essi renderanno il documento non in modalità standard, ma in una modalità di compromesso che ripropone i bug delle versioni precedenti. Esempio: l'interpretazione del box model in Explorer 5.x. Se non inserite il giusto DOCTYPE, Explorer 6 lavorerà in modalità non standard e riproporrà il comportamento (errato) dei suoi predecessori. Sempre a proposito di Explorer 6, vi segnalo che se costruite un documento XHTML inserendo in alto la dichiarazione XML, il browser lavorerà in modalità non-standard (sic!). Soluzione: non inseritela perchè non è obbligatoria.
Gli articoli sull'argomento si sono ultimamente moltiplicati perchè la questione lo merita. Vi rimando ad essi per approfondimenti e per un analisi dei DOCTYPE da adottare per far lavorare i browser in modalità standard:
- Fix
your site with the right DOCTYPE: Jeffrey Zeldman su A list apart. Completo
e ricco di link - DOCTYPE explained: sul sito di Apple un'ottima spiegazione relativa a Explorer 5 Mac
- Mozilla's DOCTYPE sniffing: il DOCTYPE in Mozilla e nei browser basati su Gecko
- Explorer 6 e i CSS: l'articolo citato in precedenza presenta un utile approfondimento con esempi sull'argomento DOCTYPE
Abbiamo visto come sia possibile realizzare layout fluidi e indipendenti dalla risoluzione. La soluzione del layout fluido per il problema della visualizzazione di una pagina a risoluzione diverse è solo una di quelle possibili. Il sito di HTML.it, per esempio, ne sfrutta un'altra altrettanto comune: la costruzione di un box centrato largo 768px (che nella pratica è una tabella). Alla risoluzione di 1024x768, il box avrà ai lati due zone di uguale ampiezza con il colore scelto per lo sfondo, a 800x600 occuperà, più o meno, l'intera ampiezza della finestra del browser.
Con i CSS è ovviamente possibile ottenere un risultato analogo e dire addio all'intrico di tabelle e sottotabelle. Per quest'ultima lezione torneremo all'esempio proposto nella prima parte e lo realizzeremo insieme cogliendo l'opportunità di affrontare altre questioni rilevanti sui layout con i CSS.
Struttura della pagina
L'esempio su cui lavoreremo è la conversione in CSS e XHTML valido della pagina principale della sezione PRO HTML.it. È il frutto di un paio d'ore di lavoro, iniziate con lo studio delle varie sezioni della pagina (figura 1).
Nell'immagine, sono state evidenziati con il testo blu i box strutturali, quelli che formano l'ossatura di base del layout; in rosso invece quelli secondari, nidificati all'interno dei primi. Insieme alla definizione della sezione viene riportata l'indicazione del selettore id (#) o delle classi (.) definiti nel CSS.
L'uso di un id o di una classe non cambia dal punto di vista visuale. Ma l'id si usa per stili da usare una sola volta nella pagina, mentre una classe può essere applicata a più elementi. Non è solo una questione di ordine concettuale: se validate un documento in cui un'id sia replicato, vi sarà segnalato un errore.
Della pagina forniamo in allegato il codice completo. Riassumendo: il layout è composto da un div usato come contenitore principale, al cui interno trovano posto gli altri. La struttura ad albero del documento può essere così schematizzata (figura 2).
Il box principale
Iniziamo con la definizione degli stili per i primi elementi della pagina: html, body, il div #box. Obiettivo in questa prima fase: impostare il div #box perchè abbia una larghezza di 768px e sia centrato nella pagina a qualunque risoluzione:
#box {
width: 768px;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
}
Per la larghezza niente problemi: si usa ovviamente la proprietà width. Ma come si fa per ottenere un box centrato automaticamente? Si sfrutta il valore auto per i margini sinistro e destro. La tecnica è stata già spiegata nel tutorial allegato alla guida a XHTML. Ricordatela, perchè è quella più valida e sicura per centrare con i CSS. Nel tutorial citato si fa riferimento anche a un bug di Explorer 5, che non interpreta bene la parola chiave "auto".
Pronta la soluzione: all'interno della definizione dello stile di body basta aggiungere l'istruzione text-align: center, badando a reimpostare l'allineamento del testo a sinistra nel box sottostante. Ecco il risultato del nostro lavoro fino a questo momento (lo sfondo del box è grigio per chiarezza esplicativa). D'ora in poi si riporta nell'esempio il codice del CSS man mano che avanziamo.
La sezione del logo
Il primo box da definire è #top: contiene il logo della sezione PRO
e presenta il classico sfondo delle testate di HTML.it.
#top {
background-color: #000066;
background-image: url(sfondo.gif);
}
Tutto molto semplice. Ci limitiamo a impostare le proprietà dello sfondo. La cosa che può stupire è che non ci siano indicazioni su larghezza, altezza o posizionamento. Non ne abbiamo bisogno. La larghezza non espressa equivale a width: auto e si adegua a quella dell'elemento parente (#box = 768px). L'altezza è data dal contenuto. Il posizionamento sarà quello del normale flusso dei dati: il div #top sarà dunque il primo elemento della pagina ed essendo un elemento blocco darà origine ad un a capo e all'inizio di un nuovo blocco subito dopo di esso.
La barra menu
Il blocco succesivo è la barra con il menu principale. Nel documento XHTML è identificata dal div #barretta. Anche qui avremo larghezza e altezza automatica: la barra si estenderà per tutta l'ampiezza del div #box. A livello di formattazione abbiamo aggiunto la definizione di un bordo superiore e di uno inferiore grigi di 2px e un pò di padding per spaziare il testo.
La cosa interessante di questo elemento è che contiene dei link. Pertanto, non può mancare la definizione delle caratteristiche del testo (bianco su sfondo nero).
Per gestire l'aspetto e il comportamento dei link ricorriamo alle pseudoclassi. Con la dichiarazione #barretta : a impostiamo l'aspetto dei link generali, con #barretta : hover il comportamento al passaggio del mouse. In questo caso il testo sarà nero e lo sfondo giallo, come nell'originale. Per approfondimenti vi rimando all'articolo : «Definire gli stili dei link con i CSS: tra estetica e usabilità».
Il menu sinistro
La nostra pagina comincia a prendere forma. È il momento di aggiungere la
barra dei menu a sinistra. Vediamone le caratteristiche:
- come sfondo usiamo la stessa immagine della testata
- il margine è di 0px: sarà adiacente ai box che lo circondano
- l'altezza è del 100%
- la larghezza di 130px
Ai fini del posizionamento la proprietà più importante è però float : left. Abbiamo accennato a questa proprietà nel primo articolo della serie, ora la vedremo in pratica. E un buono spunto ci viene proprio dal consueto esempio che ci mostra lo stato di avanzamento della pagina (visualizza). Impostando il float col valore left, il box viene spinto verso il bordo sinistro del box contenitore (per noi il div #box). Ma osservate il testo del codice. Esso scorre intorno all'elemento.
Il div #left è così posizionato. Una considerazione importante va fatta sulla larghezza: se usate il float per posizionare elementi specificatela sempre. Senza di essa ottereste questo risultato. La larghezza sarà quella del contenuto e l'effetto non sarà certo quello desiderato.
Completiamo la struttura
A questo punto definiamo le altre colonne del layout: quella centrale (div #middle) e quella destra (div #right). Per posizionare usiamo ancora una volta il float: entrambi i div, analogamente al menu sinistro, hanno larghezza fissa, float a sinistra, margini a 0px, altezza al 100%:
#middle {
width: 508px;
float: left;
height: 100%;
margin: 0px;
}
#right {
float: left;
width: 130px;
height: 100%;
margin: 0px;
}
Il posizionamento dei tre div avviene come per un gioco ad incastro. Il div #left si posiziona sul bordo del box contenitore, il div #middle cercherà di fare altrettanto, ma troverà al suo fianco #left e, se c'è spazio si posizionerà accanto ad esso. Così avverrà per #right rispetto a #middle. Nel nostro caso lo spazio c'è per tutti e tre! È preciso. Se fate la somma delle tre larghezze avrete: 130 + 508 + 130 = 768. La larghezza del div #box. Forse stanno un pò stretti, ma è quello che volevamo ottenere! Ed ecco quello che succede se lo spazio non ci fosse (abbiamo aumentato a 330px la larghezza del div #left): i div adiacenti a #left andrebbero a cercarsi posto in basso.
Il funzionamento dovrebbe essere chiaro. Chiudo con un consiglio: potreste usare per i tre div larghezze in percentuale, nulla lo vieta. Ma la scelta delle tre percentuali dovrebbe essere fatta dopo tante prove per verificare il comportamento dei div a diverse risoluzioni, ridimensionando le finestre e con browser diversi. Con dimensioni in pixel tutto è più facile.
Visualizza l'esempio con il codice.
Riempiamo i box: il menu sinistro
A questo punto il layout di base è completato, ma per completezza è giusto accennare alla definizione degli stili per le altre sezioni. Iniziamo dal menu sinistro. I vari div sono formattati con l'uso delle sguenti classi:
- homepage
- menu
- preferiti
- testopref
Tutte le classi hanno larghezza automatica: il valore sarà quello del box parente, quindi 130px. Sulle classi .homepage, .preferiti e .testopref non spendiamo molte parole. Si tratta di impostazioni relative all'aspetto facilmente ricavabili dall'esame del codice.
Più complessa la classe .menu, quella che definisce l'elenco dei link interni della sezione PRO. La difficoltà stava nel rendere l'aspetto vagamente tridimensionale della tabella e di replicare l'effetto rollover. Tutto è stato fatto senza usare tabelle e immagini di alcun tipo, come quelle che servono nell'orginale alla resa dei bordi. La tecnica è quella vista negli articoli sui Rollover di navigazione con i CSS e sulle tabelle 3D già pubblicate. Si procede così:
- con la classe .menu si definiscono le proprietà dello sfondo e del testo
- con .menu : a si imposta l'aspetto dei link (meglio: dell'elemento <a>)
- con .menu a : hover si crea l'effetto rollover
La maggiore complessità riguarda la classe .menu : a. A parte le proprietà del testo è fondamentale notare la dichiarazione display : block. Settando quest'ultima ottengo il risultato di mostrare ogni link su una riga diversa, senza fare uso di paragrafi. È decisivo, perchè in genere l'elemento <a> che definisce i link è di tipo inline, viene cioè definito all'interno di porzioni di testo e non dà orgine ad una nuova riga. In questo modo ottengo una bella barra dei menu, il cui effetto 3D è dato dalla particolare definizione e combinazione dei bordi superiore e inferiore (1px bianco quello inferiore, 1px nero quello superiore) con il colore di sfondo.
Riempiamo i box: la colonna centrale
La colonna centrale si articola in quattro sezioni (figura 1). Anche qui poco da evidenziare. L'unica lieve difficoltà consiste nella resa visiva del form del box di ricerca. Innanzitutto, abbiamo impostato i margini del form stesso a 0px: Internet Explorer tende infatti ad inserire uno spazio di alcuni pixel intorno agli elementi del form, il che avrebbe espanso l'altezza del div.
Una dichiarazione è stata dedicata anche al tag <input>: lo scopo era quello di allineare al centro l'immagine usata come pulsante di invio.
Un ultimo ritocco
Se visualizzate lo stato del lavoro fino al punto precedente, noterete che l'altezza delle due colonne laterali non si estende per tutto il documento. Abbiamo già spiegato questo comportamento negli articoli precedenti. Per risolvere tutto basta assegnare come immagine di sfondo al div #box la stessa usata per le colonne laterali. Il risultato sarà quello visibile nel documento iniziale.
Siamo alla fine. L'ultimo consiglio sembrerà banale: studiate, sperimentate, giocate con il codice. Con la consapevolezza che il futuro è questo. Vi propongo due eccellenti fonti di ispirazione e approfondimento:
- CSS Discuss - È la mailing list creata e curata da Eric Meyer. Ogni giorno decine di messaggi e discussioni su tutti gli aspetti dei CSS e su molte delle questioni toccate in queste lezioni.
- WebNouveau - prima o poi qualcuno doveva farlo: una raccolta di siti fatti senza tabelle e con i CSS. Molti sono esempi pregevoli e di grande impatto.