教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線:400-618-4000

UI培訓(xùn)之清除浮動(dòng)

更新時(shí)間:2016年04月15日14時(shí)31分 來(lái)源:傳智播客UI培訓(xùn)學(xué)院 瀏覽次數(shù):

我想大家在寫(xiě)CSS的時(shí)候應(yīng)該都對(duì)清除浮動(dòng)的用法深有體會(huì),包括我在錄制視頻的時(shí)候,我也遇到一點(diǎn)疑惑。怎么才能把這里和學(xué)生講清楚。今天我們就還討論下clearfix的進(jìn)化史吧。
clearfix清除浮動(dòng)
首先在很多很多年以前我們常用的清除浮動(dòng)是這樣的。
  1. .clear{clear:both;line-height:0;}
現(xiàn)在可能還可以在很多老的站點(diǎn)上可以看到這樣的代碼,相當(dāng)暴力有效的解決浮動(dòng)的問(wèn)題。但是這個(gè)用法有一個(gè)致命傷,就是每次清除浮動(dòng)的時(shí)候都需要增加一個(gè)空標(biāo)簽來(lái)使用。
這種做法如果在頁(yè)面復(fù)雜的布局要經(jīng)常清楚浮動(dòng)的時(shí)候就會(huì)產(chǎn)生很多的空標(biāo)簽,增加了頁(yè)面無(wú)用標(biāo)簽,不利于頁(yè)面優(yōu)化。但是我發(fā)現(xiàn)大型網(wǎng)站中 居然還在使用這種清楚浮動(dòng)的方法。有興趣的同學(xué)可以上他們首頁(yè)搜索一下他們的.blank0這個(gè)樣式名稱(chēng)。
 
因此有很多大神就研究出了 clearfix 清除浮動(dòng)的方法,直接解決了上面的缺陷,不需要增加空標(biāo)簽,直接在有浮動(dòng)的外層加上這個(gè)樣式就可以了,這也是我們今天要討論的clearfix進(jìn)化史。
起源
.clearfix:after { 
    visibility: hidden; 
    display: block; 
    font-size: 0; 
              content: " "; 
              clear: both; 
             height: 0; 

.clearfix { display: inline-table; } 
 
* html .clearfix { height: 1%; }//Hides from IE-mac 
.clearfix { display: block; }//End hide from IE-mac 
 
解釋一下以上的代碼:
  • 對(duì)大多數(shù)符合標(biāo)準(zhǔn)的瀏覽器應(yīng)用第一個(gè)聲明塊,目的是創(chuàng)建一個(gè)隱形的內(nèi)容為空的塊來(lái)為目標(biāo)元素清除浮動(dòng)。
  • 第二條為clearfix應(yīng)用 inline-table 顯示屬性,僅僅針對(duì)IE/Mac。利用 * 對(duì) IE/Mac 隱藏一些規(guī)則:
  • height:1% 用來(lái)觸發(fā) IE6 下的haslayout。
  • 重新對(duì) IE/Mac 外的IE應(yīng)用 block 顯示屬性。
  • 最后一行用于結(jié)束針對(duì) IE/Mac 的hack。(是不是覺(jué)得很坑爹,Mac下還有IE)
 
起源代碼可能也是很早期的時(shí)候了,再往后Mac下的IE5也發(fā)展到IE6了,各種瀏覽器開(kāi)始向W3C這條標(biāo)準(zhǔn)慢慢靠齊了。所以就有了下面這個(gè)寫(xiě)法出現(xiàn)了。
.clearfix:after { 
    visibility: hidden; 
    display: block; 
    font-size: 0; 
    content: " "; 
    clear: both; 
    height: 0; 

* html .clearfix { zoom: 1; } /* IE6 */ 
*:first-child+html .clearfix { zoom: 1; } /* IE7 */ 
 
IE6 和 IE7 都不支持 :after 這個(gè)偽類(lèi),因此需要后面兩條來(lái)觸發(fā)IE6/7的haslayout,以清除浮動(dòng)。幸運(yùn)的是IE8支持 :after 偽類(lèi)。因此只需要針對(duì)IE6/7的hack了。
在一個(gè)有float 屬性元素的外層增加一個(gè)擁有clearfix屬性的div包裹,可以保證外部div的height,即清除"浮動(dòng)元素脫離了文檔流,包圍圖片和文本的 div 不占據(jù)空間"的問(wèn)題。

clearfix浮動(dòng)

構(gòu)成Block Formatting Context的方法有下面幾種: 
    float的值不為none。 
    overflow的值不為visible。 
    display的值為table-cell, table-caption, inline-block中的任何一個(gè)。 
    position的值不為relative和static。 
很明顯,float和position不合適我們的需求。那只能從overflow或者display中選取一個(gè)。
 
因?yàn)槭菓?yīng)用了.clearfix和.menu的菜單極有可能是多級(jí)的,所以overflow: hidden或overflow: auto也不滿(mǎn)足需求(會(huì)把下拉的菜單隱藏掉或者出滾動(dòng)條),那么只能從display下手。 
 
我們可以將.clearfix的display值設(shè)為table-cell, table-caption, inline-block中的任何一個(gè)
 
但是display: inline-block會(huì)產(chǎn)生多余空白,所以也排除掉。
 
剩下的只有table-cell, table-caption,為了保證兼容可以用display: table來(lái)使.clearfix形成一個(gè)Block Formatting Context
 
因?yàn)閐isplay: table會(huì)產(chǎn)生一些匿名盒子,這些匿名盒子的其中一個(gè)(display值為table-cell)會(huì)形成Block Formatting Context。這樣我們新的.clearfix就會(huì)閉合內(nèi)部元素的浮動(dòng)。 
 
后面又有人對(duì)此進(jìn)行了改良:

Jeff Starr 在這里針對(duì)IE6/7用了兩條語(yǔ)句來(lái)觸發(fā)haslayout。我在想作者為什么不直接用 * 來(lái)直接對(duì) IE6/7 同時(shí)應(yīng)用 zoom:1 或者直接就寫(xiě)成:
.clearfix:after { 
    visibility: hidden; 
    display: block; 
    font-size: 0; 
    content: " "; 
    clear: both; 
    height: 0; 

.clearfix{*zoom:1;} 
 
但是對(duì)于很多同學(xué)這種優(yōu)化程度代碼還是不夠給力,clearfix 發(fā)展到現(xiàn)在的兩個(gè)終極版。
終極版一:
.clearfix:after { 
    content:"\200B"; 
    display:block; 
    height:0; 
    clear:both; 

.clearfix {*zoom:1;}/*IE/7/6*/ 
 
解釋下:content:"\200B";這個(gè)參數(shù),Unicode字符里有一個(gè)“零寬度空格”,即 U+200B,代替原來(lái)的“.”,可以縮減代碼量。而且不再使用visibility:hidden。
終極版二:
.clearfix:before,.clearfix:after{ 
    content:""; 
    display:table; 

.clearfix:after{clear:both;} 
.clearfix{ 
    *zoom:1;/*IE/7/6*/ 

其實(shí)說(shuō)了這么多,很多人對(duì).clearfix:before不是很理解,包括一開(kāi)始我也不是很理解。到底我什么時(shí)候需要用before呢?為什么方案一沒(méi)有呢?其實(shí)它是用來(lái)處理margin邊距重疊的,由于內(nèi)部元素 float 創(chuàng)建了BFC,導(dǎo)致內(nèi)部元素的margin-top和 上一個(gè)盒子的margin-bottom 發(fā)生疊加。如果這不是你所希望的,那么就可以加上before,如果只是單純的閉合浮動(dòng),after就夠了!并不是如同大漠《Clear Float》一文所說(shuō)的:但只使用clearfix:after時(shí)在跨瀏覽器兼容問(wèn)題會(huì)存在一個(gè)垂直邊距疊加的bug,這不是bug,是BFC應(yīng)該有的特性。
 
在實(shí)際開(kāi)發(fā)中,改進(jìn)方案一由于存在Unicode字符不適合內(nèi)嵌CSS的GB2312編碼的頁(yè)面,使用方案二完全可以解決我們的需求了。





本文版權(quán)歸傳智播客UI培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客UI培訓(xùn)學(xué)院
首發(fā):http://xamj520.com/ui
0 分享到:
和我們?cè)诰€交談!