Fino a che punto i float possono essere annidati? Fino a quale livello di complessità possiamo spingerci? Quando è lecito insistere sull'annidamento e qual'è il punto di rottura di un layout basato sui float? Queste e altre domande mi hanno spinto a realizzare un demo che riproduce un quadro astratto utilizzando i float. Non si tratta di un esempio fine a se stesso: è infatti un motivo di riflessione su alcune caratteristiche dei float che penso possano tornare utili nel design di layout complessi. Vediamo insieme queste caratteristiche.
Contenimento dei float
Il risultato del floating sul genitore di un elemento flottato è che il suo spazio verticale collassa. L'effetto visibile è quello di un float che fuoriesce dal suo contenitore (il genitore).
Per prevenire questo effetto si può:
- dare un'altezza al genitore
- dare la dichiarazione
overflow: hidden
al genitore - far flottare il genitore
Queste soluzioni non sono equivalenti. L'altezza data al genitore deve sempre essere proporzionale all'altezza (intrinseca o specificata) dell'elemento flottato. Usare invece il floating e l'overflow sul genitore ci permette di avere un genitore che si adatta al contenuto dei float, senza limitazioni.
Elementi flottati e elementi non flottati
Un elemento flottato "ruba" lo spazio agli altri elementi non flottati che lo circondano. L'elemento flottato si affiancherà sulla stessa riga degli elementi non flottati, a meno che lo spazio orizzontale sia insufficiente e che quindi venga spinto su una nuova riga.
Per ripristinare il normale flusso del documento e per permettere agli elementi non flottati di essere visualizzati su una riga a parte si usa la proprietà clear
applicata all'elemento non flottato che segue l'elemento con float.
L'unico svantaggio dell'uso di questa proprietà è che i browser calcolano in modo diverso il margine superiore dell'elemento a cui viene applicato il clear. In tal senso si può usare il padding superiore in alcuni casi, o utilizzare un elemento annidato all'interno di tale elemento e specificare solo su quest'ultimo il margine superiore.
Il demo
Il demo ha la seguente marcatura:
<div id="box">
<div id="left">
<div id="left1">
<div id="lefta">
<div id="subleft">
<div id="subleft1"></div>
<div id="subleft2"></div>
<div id="subleft3"></div>
</div>
<div id="subright"></div>
</div>
<div id="leftb"></div>
<div id="leftc"></div>
</div>
<div id="left2"></div>
<div id="left3"></div>
</div>
<div id="right"></div>
</div>
E il seguente CSS:
#box {
margin: 0 auto;
width: 600px;
height: 600px;
background: #0c0;
color: #fff;
}
#left {
margin: 0;
width: 300px;
height: 600px;
background: #ffc;
color: #000;
float: left;
}
#right {
margin: 0;
width: 300px;
height: 600px;
float: right;
}
#left1 {
margin: 0;
width: 100px;
height: 300px;
background: green;
float: left;
}
#left2 {
margin: 0;
width: 100px;
height: 300px;
background: yellow;
float: left;
}
#left3 {
margin: 0;
width: 100px;
height: 300px;
background: lime;
float: left;
}
#lefta, #leftb, #leftc {
width: 100px;
height: 100px;
margin: 0;
}
#lefta {background: #00f;}
#leftb {background: #693;}
#leftc {background: teal;}
#subleft {
float: left;
margin: 0;
width: 50px;
height: 100px;
background: maroon;
}
#subleft1 {
float: left;
width: 25px;
height: 25px;
background: pink;
}
#subleft2 {
float: right;
width: 25px;
height: 25px;
background: fuchsia;
}
#subleft1, #subleft2 {margin: 0;}
#subleft3 {
clear: both;
margin: 0;
height: 50px;
background: orange;
}
#subright {
float: right;
margin: 0;
width: 50px;
height: 100px;
background: purple;
}
Notiamo che i float in questo caso sono spesso autocontenuti dal loro genitore, che ha sempre un'altezza esplicita. Occorre calcolare sempre le dimensioni complessive degli elementi al fine di evitare problemi di sovrapposizione o di superamento dei limiti del box.
Potete visionare il demo in questa pagina.