Senza dubbio i float sono uno dei mezzi più potenti e diffusi per realizzare layout. Ne abbiamo parlato già in moltissime occasioni. C'è però ancora una tecnica di cui non abbiamo parlato.
Inizialmente presentata su A List Apart, la tecnica dei margini negativi è semplice, versatile ed è indicata per una certa classe di layout. Vedremo qui la versione a due e tre colonne: ma prima di addentrarci nell'esame di codice ed esempi, vediamo le caratteristiche e i possibili usi.
Caratteristiche del layout
I margini negativi si usano generalmente per realizzare layout liquidi a due e tre colonne in cui le colonne laterali hanno larghezza fissa. Per ottenere l'effetto desiderato è necessaria una particolare codifica HTML, in cui la disposizione dei contenuti è ben definita, e sono necessari alcuni contenitori aggiuntivi. Se questo può essere un eccesso di markup, si consideri che avere la colonna dei contenuti spostata verso la cima del codice può costitutire un benefit per l'accessibilità e i motori di ricerca. Ma non indugiamo oltre e passiamo agli esempi.
La versione a due colonne
Vediamo subito l'esempio: si tratta di un layout liquido a due colonne realizzato con i margini negativi. Ecco l'HTML di base:
<div id="container">
<div id="header">header</div>
<div id="wrapper">
<div id="content">contenuto</div>
</div>
<div id="sidebar">navigazione</div>
<div id="footer">footer</div>
</div>
Prima di addentrarci nel CSS, due commenti sul markup. La cosa essenziale da notare è che il div id="content" è racchiuso da un div id="wrapper" e che entrambi precedono la navigazione. Il wrapper è un contenitore aggiuntivo che ha lo scopo di fornire un appoggio al foglio di stile.
Il foglio di stile
Il foglio di stile dell'esempio è piuttosto semplice e non fa uso di hack. Vediamolo passo passo. Per prima cosa vengono rimossi i margini e il padding della pagina, viene definito lo sfondo sul container per le false colonne (cfr. Articolo «False colonne») e le regole per l'header:
html,body{margin: 0;padding: 0}
body{font: 100.01% Arial,sans-serif}
div#container{width: 100%;background: #FFF url(col.jpg) repeat-y right}
div#header{background: #555B65;color: #FFF}
div#header h1{margin:0 0 20px;padding: 10px 20px;font-size: 200%}
La dichiarazione width:100% è superflua e ininfluente, e serve solo per sistemare un difetto di resa dello sfondo di IE5.
Ora arriviamo alla parte essenziale. Per applicare i margini negativi il wrapper assumerà la larghezza del contenitore (il 100%), verrà reso float e traslato a sinistra di 200 pixels, così da lasciare posto per la colonna di navigazione che sarà resa float a destra.
Il risultato è che il wrapper verrà portato di 200px oltre il lato sinistro della finestra. Per rimettere a posto le cose i contenuti effettivi, racchiusi dal div id="content", avranno un margine sinistro di 220px (200 per riportare i contenuti all'interno dell'area visibile, più 20 per distanziarli dalla lato sinistro del viewport) e un margine destro di 20px per distanziare la colonna di navigazione. Quest'ultima viene resa float a destra. Ecco il CSS:
div#wrapper{float: left;width: 100%;margin-left: -200px}
div#content{margin: 0 20px 0 220px}
div#sidebar{float: right;width: 180px;
margin-right: 10px;display: inline;font-size: 80%}
Da notare che la colonna di navigazione è 180px e ha un margine destro di 10px, così da lasciare 10px sui due lati dei 200px della falsa colonna. La dichiarazione display:inline serve per sistemare un noto bug di IE che raddoppia i margini concordi con il float.
Infine la regola sul footer. Per un layout robusto e per far sì che che non ci siano vincoli sulla larghezza relativa delle colonne basterà dare il clear su entrambi i lati:
div#footer{clear:both;padding: 3px 20px;background: #959FB1}
Tutto qui. Con delle regole logiche e semplici abbiamo ottenuto un layout robusto e con una resa cross-browser molto estesa: Il risultato è stato infatti testato su IE 5,5.5 e 6, Opera, Mozilla e Safari. Lo stesso principio può essere applicato ad un layout a tre colonne, vediamo come.
La versione a tre colonne
Vediamo subito l'esempio. Una volta capito il meccanismo dei margini negativi è facile estendere l'idea e ottenere un layout a tre colonne. Ovviamente ci sono aggiunte nell'HTML e nel CSS, ma il principio di base è comune. Ecco l'HTML:
<div id="container">
<div id="container2">
<div id="header">header</div>
<div id="wrapper">
<div id="nav">colonna di sinistra</div>
<div id="content">contenuto</div>
</div>
<div id="sidebar">colonna di destra</div>
<div id="footer">footer</div>
</div>
</div>
Come si può notare, rispetto alla versione a due colonne ci sono due contenitori aggiuntivi: un div id="container2" che ha lo scopo di contenere una delle immagini per le false colonne e ovviamente il div id="nav" che rappresenta la colonna di sinistra. C'è da notare che questo div precede i contenuti e sono entrambi racchiusi dal wrapper.
Vediamo per prima cosa gli stili di pagina, sui due contenitori principali e sull'header:
html,body{margin:0;padding:0}
body{font:100.01% Arial,sans-serif}
p{margin: 0 0 1em;line-height:1.4}
div#container{width: 100%;background: url(col2.jpg) repeat-y left}
div#container2{background: url(col.jpg) repeat-y right}
div#header{background: #555B65;color: #FFF}
div#header h1{margin:0 0 20px;padding: 10px;font-size: 200%}
Ora la parte centrale del CSS. Anche in questo caso il wrapper è reso float a sinistra, assume una larghezza pari al 100% della finestra del browser ed è traslato verso sinistra di 200px grazie ai margini negativi. Tale valore è proprio la larghezza dell'area dedicata alla colonna di destra, che verrà resa float:
div#wrapper{float: left;width: 100%;margin-left: -200px}
div#sidebar{float: right;width: 180px;
margin-right: 10px;display: inline;font-size: 80%}
Ci restano da sistemare la navigazione di sinistra e i contenuti. Il div id="nav" verrà reso float a sinistra, avendo cura di attribuirgli un margine pari almeno alla traslazione orizzontale del wrapper. Avrà quindi un margine sinistro di 210 px, sarà largo 180px e avrà un margine destro di 10px. Come nell'esempio a due colonne e per la colonna di destra, la dichiarazione display:inline viene usata per sistemare il bug di IE che raddoppia i margini.
div#nav{float: left;width: 180px;display: inline;
margin:0 10px 0 210px;font-size: 80%}
Arriviamo ai contenuti: questi subiscono la traslazione di 200px della pagina e la presenza della colonna di sinistra, larga 200px. Aggiungiamo un margine sinistro di 10px per distanziarlo dalla navigazione, e capiremo che per avere i contenuti al loro posto, e far si che questi restano distanti anche quando termina la colonna di sinistra, sono necessari 410px di margine sinistro:
div#content{margin: 0 10px 0 410px;
height:auto !important;height: 1%}
Da notare che le due dichiarazioni sull'altezza non sono indispensabili, e servono solo per sistemare un noto bug di IE, ovvero il 3 pixel jog (cfr. articolo:«3 pixel jog»). Infine la regola sul footer:
div#footer{clear: both;padding: 3px 10px;background: #959FB1}
Il layout a tre colonne è così pronto: anche in questo caso la resa è stata testata ed è perfetta su IE 5, 5.5 e 6, Opera, Mozilla e Safari.
Conclusioni
Abbiamo visto come poter realizzare layout a due e tre colonne con l'uso dei margini negativi, una tecnica che si rivela semplice e robusta una volta capita la sottile logica dell'implementazione. Per approfondimenti rimando a questo ottimo tutorial.
Codice ed esempi sono disponibili per il download. Alla prossima.