種方法都盡善盡美。閉合浮動元素(或者叫清除浮動)是web标準設計中經常會遇到的一個問題,是以,這裡我想總結一下目前經常用到的幾種方法,并比較一下他們的易用性和适用環境。如果你有更好的方法不妨提出來大家一起讨論。
問題的提出:
最簡單的一種情形就是我們把一個小的、固定寬度的div元素(比如導航、引用等)和其他元素内容一起包含在一個大的div中。比如下面這段代碼:
view plain copy to clipboard print ?
- <div id="outer">
- <div id="inner"> <h2>A Column</h2> </div>
- <h1>Main Content</h1>
- <p>Lorem ipsum</p>
- </div>
<div id="outer">
<div id="inner"> <h2>A Column</h2> </div>
<h1>Main Content</h1>
<p>Lorem ipsum</p>
</div>
我們可以為“#inner”設定一個寬度值(比如說20%),但是由于div是塊級元素,即使我們設定了寬度,其後面的内容也隻能在下一行中顯示,除非我們給它設定一個浮動屬性(無論是向左浮動或者向右浮動)。那麼此時會産生我們上面提到的問題了。
如果“#inner”的寬度和高度都比“#outer”小,這不會有問題。
但是,如果“#inner”的高度超過了“#outer”,那麼的底部就會超出“#outer”的底部。這是因為我們為“#inner”設定了float屬性後,它就會脫離的文本流,無論其寬度和高度怎麼變化都不會使“#outer”跟随變化。
例一:未清除浮動時的布局表現
在這個例子中,最開始由于“#inner”的高度小于“#outer”是以不會有問題,但是當你點選“加長”後你會發現“#inner”的底邊已經超出了“#outer”的範圍,而“#outer”沒有發生改變。這就是我們所提到的“清除浮動(閉合浮動元素)”或者是“閉合浮動”問題
解決辦法:
1)額外标簽法
第一個,也是W3C推薦的方法就是使用額外标簽的辦法。這種方法就是在内容的末尾增加一個空的标簽,典型的做法就是使用類似
view plain copy to clipboard print ?
- <br style="clear:both;" />
<br style="clear:both;" />
或者使用
<div style="clear:both;"></div>
這種辦法通過增加一個HTML元素迫使外部容器撐開。不過這個辦法會增加額外的标簽使HTML結構看起來不夠簡潔。
例二:使用空div閉合浮動元素
P.S. 我發現在Internet Explorer中(無論是6還是7)<br style="clear:both" />可以清除浮動,但是不能閉合浮動元素,在Firefox中就沒有這個問題,不知道是什麼原因?!
2)使用after僞類
使用after僞類和内容聲明在指定的現在内容末尾添加新的内容。經常的做法就是添加一個“點”,因為它比較小不太引人注意。然後我們再利用它來清除浮動(閉合浮動元素),并隐藏這個内容:
view plain copy to clipboard print ?
- #outer:after{
- content:".";
- height:0;
- visibility:hidden;
- display:block;
- clear:both;
#outer:after{
content:".";
height:0;
visibility:hidden;
display:block;
clear:both;
但奇怪的是Windows中的Internet Explorer 6及以下版本并不支援CSS 2.1中的after僞類而Mac中的Internet Explorer卻可以正常使用,是以我們還要單獨針對Win/IE進行處理。在區分Win和Mac中Internet Explorer的諸多方法中,最常用就是Holly招數。Holly招數的原理是這樣的,CSS代碼
view plain copy to clipboard print ?
- CSS 規則
/* 這段代碼隻有IE/Win可以看見 \*/
CSS 規則
/* 結束Hack */
上面的代碼中有兩行注釋,其中第一行結束時出現了反斜杠(\),在Mac的Internet Explorer中會認為注釋并沒有結束,于是繼續向下直到第一個完事的“*/”出現,這中間的所有字元都被當作是注釋,而IE/Win卻也隻會把第一行和第三行看作是注釋,中間的為有效代碼。是以這樣就區分出來了不同平台上的IE了。
正是基于以上原理,在windows的IE 6上的清理浮動,可以使用如下代碼:
view plain copy to clipboard print ?
- #outer {
- display:inline-block;
- }
- * html #outer {
- height:1%;
- }
- #outer {
- display:block;
- }
#outer {
display:inline-block;
}
/* Holly Hack Begine \*/
* html #outer {
height:1%;
}
#outer {
display:block;
}
/* End Hack */
例三:使用:after僞類清理浮動
P.S. 如果你不考慮 IE6/Mac使用者的話你隻需要寫* html #outer {height:1%;}即可。
另外,似乎在Internet Explorer 7中不高display:inline-block也不好使。是以要使用最完整的Hack招數。
如果你對如何使用CSS 2中的僞類不熟悉的話,推薦你先閱讀一下“細說CSS樣式選擇符——CSS 2.1 Selectors(1)、(2)、(3)”
3)浮動外部元素,float-in-float
這種方法很簡單,就是把“#outer”元素也進行浮動(向左或者向右)。
例子
但是這種方法帶來的别外一個問題就是和“#outer”相鄰的下一個元素會受到“#outer”的影響位置會産生變化,是以使用這種方法一定要小心。有選擇把頁面中的所有元素都浮動起來,最後使用一個适當的有意義的元素(比如頁腳)進行清理浮動,這有助于減少不必要的标記,但是過多的浮動會增加布局的難度。
例四:float-in-float
4)設定overflow為hidden或者auto
把“#outer”的屬性overflow值設定為hidden或者auto同樣可以清理浮動
這種方法不需要添加額外的标記。但是使用overflow的時候一定要小心,因為它會浏覽器的表現。另外,在Internet Explorer 6中單純地設定overflow為hidden或者auto并不能有效清除浮動(閉合浮動元素),還要指定“#outer”的一個次元,即要麼給它指定一個寬度,要麼指定一個高度:
#outer {
overflow:auto;
width:100%;
}
注意:如果你要在IE5/Mac上使用這種方法清除浮動(閉合浮動元素)的話,你就必須設定overflow的屬性為值為hidden。
例五:overflow:hidden
比較與選擇
四種方法中使用哪種最好呢?首先,不推薦使用after僞類,對比其它三種方法,holly招數有點太煩瑣,不好掌握,我上面講到的holly招數中并不僅僅是IE/Win上有問題,當出現:hover時還會有其它問題,是以我們又加上了inline-block等屬性,也就是說這種方法存在更多的不确定性。推薦對代碼有“潔癖”并且技術較高的人使用。
那麼其它三種方法其實都可以考慮。
- 不過使用overflow的時候,可能會對頁面表現帶來影響,而且這種影響是不确定的,你最好是能在多個浏覽器上測試你的頁面;
- 而對于使用額外标簽清除浮動(閉合浮動元素),是W3C推薦的做法。至于使用<br />元素還是空<div></div>可以根據自己的喜好來選(當然你也可以使用其它塊級元素)。不過要注意的是,<br />本身是有表現的,它會多出一個換行出來,是以要設定它的heigh為0,以隐藏它的表現。是以大多數情況下使用空<div>比較合适。
- float-in-float,也是一個很好的選擇,把你要進行清理浮動的元素外層再加上一層<div>并設定屬性fload:left即可,不過要注意相鄰元素的變化。