提示:本文不是教程,而是對閉合浮動元素的方法在某個特定情況下的現象的討論,涉及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,當然這可能影響到結構,還需要結合具體情況來決定。