提示:本文不是教程,而是對閉合浮動元素的方法在某個特定情況下的現象的討論,涉及float、clear、overflow、:after等知識,新手勿入。
float屬性在頁面排版上非常有用,但是也帶來很多問題。最常見的就是浮動元素的閉合問題。
如果一個沒有設定高度的不浮動元素的子元素浮動,則該元素的高度不會包括浮動子元素的高度,而只會包含其內部不浮動元素的高度,因為浮動元素不屬於常規流向,它脫離了文檔流。因此如果要元素能夠自動包含浮動子元素,則需要閉合浮動元素。
目前比較常用的有3種方法:
- 利用浮動子元素後的元素清除浮動(包括添加1個空的元素以清除浮動)。
- 使用:after偽元素,在元素最後插入清除。
- 為元素設定overflow屬性除“visible”之外的值。
還有1個方法可以使元素自適應高度:
下列代碼,其顯示如圖1所示。
提示:所列代碼只是關鍵代碼,完整代碼請查看示例頁面。
CSS:

p,

div {

margin: 5px;

}

.wrap {

width: 440px;

margin: 10px;

clear: both;

}

.div1,

.div2p {

float: left;

width: 80px;

margin: 8px;

+display: inline;

}

XHtml:

<div class="wrap">

<div class="div1">div1,浮動</div>

<div class="div2">

<p class="div2p">div2內p1</p>

<p class="div2p">div2內p2</p>

<p class="div2p3">div2內p3,不浮動</p>

</div>

<div class="div3">div3,不浮動</div>

</div>
提示:截圖是Firefox 2.0(以下簡稱FF)中的效果,如無特殊聲明,則表示在Windows IE7.0(以下簡稱IE)、Opera 9.2(以下簡稱Op)、Safari 3.0(以下簡稱Sa)中效果相同。
圖1:浮動元素與子元素浮動的元素

如果對.div2p增加CSS:

.div2p {

......

clear:left;

}
由於“clear:left”含義為:不允許本元素左邊有浮動框,而div1也是浮動元素,因此,p1和p2下移到了div1的下面,如圖2所示。
圖2:不浮動的元素內的浮動子元素設定“clear:left”後的效果

而在IE中,整個div2都將下移到div1下,如圖3所示。
圖3:不浮動的元素內的浮動子元素設定“clear:left”後IE的顯示

由圖3可以發現,雖然在圖1中IE正確地顯示了溢出的元素,但是,對於出發了layout的wrap,IE仍舊會擴展最外層的高度,以容納浮動元素。
閉合浮動元素方法1
此時,div2的高度只包括其內未浮動元素的高度,因此使用第1種方法閉合浮動元素,為浮動元素後面的元素p3設定clear屬性:

.div2p3 {

clear:left;

}
此時顯示如圖4所示,在IE中如圖5所示。
圖4:p3清除浮動後的效果

圖5:p3清除浮動後IE內的效果

(啊!偉大的IE,居然多出來與div2的margin一樣多的間隙。= =b)
此時如果為div2增加左邊距(原設定為margin:5px):

.div2 {

......

margin-left: 120px;

}
則顯示如圖6所示,在IE中如圖7所示。
圖6:增加左邊距後的效果

圖7:p增加左邊距後IE內的效果

至此的效果,是左右2欄布局常用的方法,左欄固定寬度,右欄不設定寬度以求能自適應。
閉合浮動元素方法2
嘗試方法2,利用:after清除浮動:

.div2:after {

content: ".";

display: block;

height: 0;

clear: both;

visibility: hidden;

}
顯示效果如圖8所示。(IE不支持,不用試了。= =b)
圖8:使用:after清除浮動

可以看到div2內的p3沒有清除浮動,位置仍在div2的頂端。
增加div2的左邊距,顯示如圖9所示。

.div2 {

margin-left:120px;

}
圖9:增加div2的左邊距

由此可見使用:after清除浮動,不適合於浮動元素後面還有不浮動元素的情況。
閉合浮動元素方法3
嘗試方法3,使用overflow屬性:

.div2 {

overflow:auto;

+height:100%; /* 針對IE6 */

}
此時,最熱鬧的情況出現了:
圖10:FF的效果

圖11:Op和Sa的效果

圖12:IE的效果(注:如果用IE 6,效果也不一樣,= =|||)

首先,div2的寬度收縮到div1的右邊了,也許這正好是期望的結果?
更熱鬧的在後面,增加div2的margin-left:

.div2 {

margin-left:120px;

}
圖13:FF的效果

圖14:Op和Sa的效果

圖15:IE的效果(注:如果用IE 6,效果也不一樣,= =|||)

都是margin-left惹的禍,去掉margin-left:

.div2 {

margin-left: 0;

}
終於接近統一了。
圖16:去掉margin-left的效果

圖17:去掉margin-left在IE內的效果

由此可見,overflow還是有很大局限性的。
但是造成FF、Op和Sa的顯示結果的原因又是什麼呢?
浮動
div2浮動,浮動元素的高度會包含其內部的浮動元素。
這種方法的局限性就是,div2浮動後寬度會被壓縮,因此必須給它一個寬度值,但是這樣就無法自適應寬度。

.div2 {

float: left;

}

.div3 {

clear: both;

}
效果如圖18所示。
圖18:浮動div2

div2的浮動,還會造成wrap的高度問題,因此需要div3清除浮動。
由這個例子可以發現,由於div2的浮動,其內的p元素清除浮動,並沒有受到div1的影響,因此,解決由於前2種方法中p1和p2下降到div1的高度之下的方法之一,可以將p1和p2外面套1個浮動的div,當然這可能影響到結構,還需要結合具體情況來決定。