css 清除浮動 clearfix

在學習做一個顯示圖片的網頁的時候,使用的方法是一個div父框架,包含幾個子div,佈局需要,子div全部設置成了左浮動,然後在通過瀏覽器看父div的高度一直是0,然後看一個教程說是這種情況下需要清除浮動,用的clearfix方法,當時不太理解這個方法,然後查了資料之後明白了這兒有很大的學問呢。

查看的資料:http://www.jb51.net/css/67471.html 《浮動從何而來 我們爲何要清除浮動 清除浮動的原理是什麼》講的很精確深入

接下來主要記下自己的收穫理解:

1、浮動(float)

浮動的框可以向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框爲止。
由於浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣。

我所理解的浮動脫離文檔流,可以看成兩個上下放着的相框,下邊那個相框是文檔流,裏面放的相片可以佈局但是必須和這個相框在一個平面,上面的相框用來存放浮動框,比較自由方便佈局,如果從俯視的角度看,他們的佈局效果在同一個平面。(理解方式不一定對,只是更形象的自我理解)

2、出現問題

從相框角度去思考的話,一種情況就是下面的相框(文檔流)如果高度比較小甚至是0,二上面的相框(浮動框)高度比下面的高,就出現了問題,稱之爲“高度塌陷”,這種情況對我們的佈局,以及父div的高度等等有很大影響。

3、解決方案

上面鏈接的文章中提到其中解決方法,其中前六種不夠理想,具體如下(直接使用原文講解):

1)添加額外標籤
通過在浮動元素末尾添加一個空的標籤例如

,其他標籤br等亦可。

<div class="warp" id="float1"> 
<h2>1)添加額外標籤</h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
<div style="clear:both;"></div> 
</div> 
<div class="footer">.footer</div> 

優點:通俗易懂,容易掌握
缺點:可以想象通過此方法,會添加多少無意義的空標籤,有違結構與表現的分離,在後期維護中將是噩夢,這是堅決不能忍受的。

2)使用 br標籤和其自身的 html屬性
這個方法有些小衆,br 有 clear=“all | left | right | none”

<div class="warp" id="float2"> 
<h2>2)使用 br標籤和其自身的 html屬性</h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
<br clear="all" /> 
</div> 
<div class="footer">.footer</div> 

優點:比空標籤方式語義稍強,代碼量較少
缺點:同樣有違結構與表現的分離,不推薦使用

3)父元素設置 overflow:hidden
通過設置父元素overflow值設置爲hidden;在IE6中還需要觸發 hasLayout ,例如 zoom:1;

<div class="warp" id="float3" style="overflow:hidden; *zoom:1;"> 
<h2>3)父元素設置 overflow </h2> 
<div class="main left">.main{float:left;}</div> 
<div class="side left">.side{float:right;}</div> 
</div> 
<div class="footer">.footer</div>

優點:不存在結構和語義化問題,代碼量極少
缺點:內容增多時候容易造成不會自動換行導致內容被隱藏掉,無法顯示需要溢出的元素;04年POPO就發現overflow:hidden會導致中鍵失效,這是我作爲一個多標籤瀏覽控所不能接受的。所以還是不要使用了
4)父元素設置 overflow:auto 屬性
同樣IE6需要觸發hasLayout,演示和3差不多
優點:不存在結構和語義化問題,代碼量極少
缺點:多個嵌套後,firefox某些情況會造成內容全選;IE中 mouseover 造成寬度改變時會出現最外層模塊有滾動條等,firefox早期版本會無故產生focus等, 請看 嗷嗷的 Demo ,不要使用

方案3、4通過overflow閉合浮動,實際上已經創建了新的
塊級格式化上下文,這將導致其佈局和相對於浮動的行爲等發生一系列的變化,清除浮動只不過是一系列變化中的一個作用而已。所以爲了閉合浮動去改變全局特性,這是不明智的,帶來的風險就是一系列的bug,比如firefox
早期版本產生
focus,截斷絕對定位的層等等。始終要明白,如果單單只是需要閉合浮動,overflow就不要使用,而不是某些文章所說的“慎用”。

5)父元素也設置浮動
優點:不存在結構和語義化問題,代碼量極少
缺點:使得與父元素相鄰的元素的佈局會受到影響,不可能一直浮動到body,不推薦使用
6)父元素設置display:table
優點:結構語義化完全正確,代碼量極少
缺點:盒模型屬性已經改變,由此造成的一系列問題,得不償失,不推薦使用

上面幾種方法主要是從添加一個空標籤或者在父元素中設置overflow或浮動等方式,都有很大缺陷。
第七種方法也是目前最常用的比較好的方法:使用:after 僞元素
(7)使用:after 僞元素

需要注意的是
:after是僞元素(Pseudo-Element),不是僞類(某些CSS手冊裏面稱之爲“僞對象”),很多清除浮動大全之類的文章都稱之爲僞類,不過csser要嚴謹一點,這是一種態度。
由於IE6-7不支持:after,使用 zoom:1觸發 hasLayout。 該方法源自於: How To Clear Floats
Without Structural Markup

<style type="text/css"> 
.clearfix:after { 
content: "."; 
display: block; 
height: 0; 
clear: both; 
visibility: hidden; 
} 
.clearfix {display: inline-block;} /* for IE/Mac */ 
</style> 
<!--[if IE]> <style type="text/css"> 
.clearfix {zoom: 1;/* triggers hasLayout */ 
display: block;/* resets display for IE/Win */} 
</style> 
<![endif]--> 

鑑於 IE/Mac的市場佔有率極低,我們直接忽略掉,最後精簡的代碼如下:

.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } 
.clearfix { *zoom:1; } 

優點:結構和語義化完全正確,代碼量居中
缺點:複用方式不當會造成代碼量增加

通過對比,我們不難發現,其實以上列舉的方法,無非有兩類: 其一,通過在浮動元素的末尾添加一個空元素,設置
clear:both屬性,after僞元素其實也是通過 content 在元素的後面生成了內容爲一個點的塊級元素; 其二,通過設置父元素
overflow 或者display:table 屬性來閉合浮動,

之後上面鏈接的文章中講了關於BFC(Block formatting contexts 塊級格式化上下文),講解清楚浮動的原理,我對BFC理解的還不夠深,有興趣可以通過鏈接去看。

四、方法優化
原文中提到兩種方法來對第七種方法進行優化

上面已經列舉了7種閉合浮動的方法,通過BFC原理,我們發現其實更多的:display:table-
cell,display:inline-block等只要觸發了BFC的屬性值都可以閉合浮動。從各個方面比較,after僞元素閉合浮動無疑是相對比較好的解決方案了,下面詳細說說該方法。

.clearfix:after {content:"."; display:block; height:0; visibility:hidden; clear:both; } 
.clearfix { *zoom:1; } 

1) display:block 使生成的元素以塊級元素顯示,佔滿剩餘空間; 2) height:0 避免生成內容破壞原有佈局的高度。
3) visibility:hidden 使生成的內容不可見,並允許可能被生成內容蓋住的內容可以進行點擊和交互; 4)通過
content:”.”生成內容作爲最後一個元素,至於content裏面是點還是其他都是可以的,例如oocss裏面就有經典的
content:”XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,有些版本可能content
裏面內容爲空,一絲冰涼是不推薦這樣做的,firefox直到7.0 content:”” 仍然會產生額外的空隙; 5)zoom:1 觸發IE
hasLayout。

通過分析發現,除了clear:both用來清除浮動的,其他代碼無非都是爲了隱藏掉content生成的內容,這也就是其他版本的閉合浮動爲什麼會有font-size:0,line-height:0。

優化方案一: 用U+200B 代替content裏面的點

相對於空標籤閉合浮動的方法代碼似乎還是有些冗餘,通過查詢發現Unicode字符裏有一個“零寬度空格”,也就是U+200B
,這個字符本身是不可見的,所以我們完全可以省略掉 visibility:hidden了

.clearfix:after {content:"\200B"; display:block; height:0; clear:both; } 
.clearfix { *zoom:1; }. 

缺點:Unicode字符不適合內嵌CSS的GB2312編碼的頁面。

優化方案二:

由Nicolas Gallagher 大溼提出來的,原文:A new micro clearfix
hack,該方法也不存在firefox中空隙的問題。

/* For modern browsers */ 
.cf:before,.cf:after { 
content:""; 
display:table; 
} 
.cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */ 
.cf { zoom:1; } 

原文提到這種方法需要實踐確定有沒有什麼問題,我用這種方法在我的網頁裏效果和方法7一樣,能夠清楚浮動,但是有沒有什麼缺陷,由於我本身就是個菜鳥,沒有看出來,可能需要大牛進一步鑑定了

需要注意的是: 上面的方法用到了
:before僞元素,很多人對這個有些迷惑,到底我什麼時候需要用before呢?爲什麼方案一沒有呢?其實它是用來處理margin邊距重疊的,由於內部元素
float 創建了BFC,導致內部元素的margin-top和 上一個盒子的margin-bottom
發生疊加。如果這不是你所希望的,那麼就可以加上before,如果只是單純的閉合浮動,after就夠了!並不是如同大漠《Clear
Float》一文所說的:但只使用clearfix:after時在跨瀏覽器兼容問題會存在一個垂直邊距疊加的bug,這不是bug,是BFC應該有的特性。

總之,方法7應該是目前清楚浮動最常用最普遍比較好的一種方法,我通過方法7已經順利清楚浮動,父div框架在瀏覽器中的調試已經能夠看到高度(裏面浮動的子div的高度)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章