日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

(转)那些年我们一起清除过的浮动

發(fā)布時(shí)間:2025/1/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (转)那些年我们一起清除过的浮动 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文轉(zhuǎn)載自:http://www.cnblogs.com/mofish/archive/2012/05/14/2499400.html

浮動(dòng)(float),一個(gè)我們即愛又恨的屬性。愛,因?yàn)橥ㄟ^(guò)浮動(dòng),我們能很方便地布局; 恨,浮動(dòng)之后遺留下來(lái)太多的問(wèn)題需要解決,特別是IE6-7(以下無(wú)特殊說(shuō)明均指 windows 平臺(tái)的 IE瀏覽器)。也許很多人都有這樣的疑問(wèn),浮動(dòng)從何而來(lái)?我們?yōu)楹我宄?dòng)?清除浮動(dòng)的原理是什么?本文將一步一步地深入剖析其中的奧秘,讓浮動(dòng)使用起來(lái)更加得心應(yīng)手。

一、清除浮動(dòng) 還是 閉合浮動(dòng) (Enclosing float or Clearing float)?

很多人都已經(jīng)習(xí)慣稱之為清除浮動(dòng),以前我也一直這么叫著,但是確切地來(lái)說(shuō)是不準(zhǔn)確的。我們應(yīng)該用嚴(yán)謹(jǐn)?shù)膽B(tài)度來(lái)對(duì)待代碼,也能更好地幫助我們理解開頭的三個(gè)問(wèn)題。

1)清除浮動(dòng):清除對(duì)應(yīng)的單詞是 clear,對(duì)應(yīng)CSS中的屬性是 clear:left | right | both | none;

2)閉合浮動(dòng):更確切的含義是使浮動(dòng)元素閉合,從而減少浮動(dòng)帶來(lái)的影響。

兩者的區(qū)別?請(qǐng)看優(yōu)雅的 Demo

通過(guò)以上實(shí)例發(fā)現(xiàn),其實(shí)我們想要達(dá)到的效果更確切地說(shuō)是閉合浮動(dòng),而不是單純的清除浮動(dòng),在footer上設(shè)置clear:both清除浮動(dòng)并不能解決warp高度塌陷的問(wèn)題。 ?

結(jié)論:用閉合浮動(dòng)比清除浮動(dòng)更加嚴(yán)謹(jǐn),所以后文中統(tǒng)一稱之為:閉合浮動(dòng)。

二、為何要清除浮動(dòng)?

要解答這個(gè)問(wèn)題,我們得先說(shuō)說(shuō)CSS中的定位機(jī)制:普通流,浮動(dòng),絕對(duì)定位 (其中"position:fixed" 是 "position:absolute" 的一個(gè)子類)。

1)普通流:很多人或者文章稱之為文檔流或者普通文檔流,其實(shí)標(biāo)準(zhǔn)里根本就沒有這個(gè)詞。如果把文檔流直譯為英文就是 document flow ,但標(biāo)準(zhǔn)里只有另一個(gè)詞,叫做?普通流?(normal flow),或者稱之為常規(guī)流。但似乎大家更習(xí)慣文檔流的稱呼,因?yàn)楹芏嘀形姆g的書就是這么來(lái)的。比如《CSS Mastery》,英文原書中至始至終都只有普通流 normal flow(普通流)?這一詞,從來(lái)沒出現(xiàn)過(guò)document flow (文檔流)

2)浮動(dòng):浮動(dòng)的框可以左右移動(dòng),直至它的外邊緣遇到包含框或者另一個(gè)浮動(dòng)框的邊緣。浮動(dòng)框不屬于文檔中的普通流,當(dāng)一個(gè)元素浮動(dòng)之后,不會(huì)影響到 塊級(jí)框的布局而只會(huì)影響內(nèi)聯(lián)框(通常是文本)的排列,文檔中的普通流就會(huì)表現(xiàn)得和浮動(dòng)框不存在一樣,當(dāng)浮動(dòng)框高度超出包含框的時(shí)候,也就會(huì)出現(xiàn)包含框不會(huì) 自動(dòng)伸高來(lái)閉合浮動(dòng)元素(“高度塌陷”現(xiàn)象)。顧名思義,就是漂浮于普通流之上,像浮云一樣,但是只能左右浮動(dòng)。

正是因?yàn)楦?dòng)的這種特性,導(dǎo)致本屬于普通流中的元素浮動(dòng)之后,包含框內(nèi)部由于不存在其他普通流元素了,也就表現(xiàn)出高度為0(高度塌陷)。在實(shí)際布局中,往往這并不是我們所希望的,所以需要閉合浮動(dòng)元素,使其包含框表現(xiàn)出正常的高度。

絕對(duì)定位就不多說(shuō)了,不在本文討論范圍之內(nèi),下回分解。

三、清除浮動(dòng)的原理——了解 hasLayout 和 Block formatting contexts

先看一下清理浮動(dòng)的各種方法:

1)添加額外標(biāo)簽

這是在學(xué)校老師就告訴我們的 一種方法,通過(guò)在浮動(dòng)元素末尾添加一個(gè)空的標(biāo)簽例如 <div style=”clear:both”></div>,其他標(biāo)簽br等亦可。

?<div class="warp" id="float1">

<h2>1)添加額外標(biāo)簽</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>

?優(yōu)雅的 Demo

優(yōu)點(diǎn):通俗易懂,容易掌握

缺點(diǎn):可以想象通過(guò)此方法,會(huì)添加多少無(wú)意義的空標(biāo)簽,有違結(jié)構(gòu)與表現(xiàn)的分離,在后期維護(hù)中將是噩夢(mèng),這是堅(jiān)決不能忍受的,所以你看了這篇文章之后還是建議不要用了吧。

?2)使用 br標(biāo)簽和其自身的 html屬性

這個(gè)方法有些小眾,br 有 clear=“all | left | right | none” 屬性

?<div class="warp" id="float2">

<h2>2)使用 br標(biāo)簽和其自身的 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>

?優(yōu)雅的 Demo

?優(yōu)點(diǎn):比空標(biāo)簽方式語(yǔ)義稍強(qiáng),代碼量較少

缺點(diǎn):同樣有違結(jié)構(gòu)與表現(xiàn)的分離,不推薦使用

?3)父元素設(shè)置 overflow:hidden

通過(guò)設(shè)置父元素overflow值設(shè)置為hidden;在IE6中還需要觸發(fā) hasLayout ,例如 zoom:1;

?<div class="warp" id="float3" style="overflow:hidden; *zoom:1;">

<h2>3)父元素設(shè)置 overflow </h2>

<div class="main left">.main{float:left;}</div>

<div class="side left">.side{float:right;}</div>

</div>

<div class="footer">.footer</div>

?優(yōu)雅的 Demo

優(yōu)點(diǎn):不存在結(jié)構(gòu)和語(yǔ)義化問(wèn)題,代碼量極少

缺點(diǎn):內(nèi)容增多時(shí)候容易造成不會(huì)自動(dòng)換行導(dǎo)致內(nèi)容被隱藏掉,無(wú)法顯示需要溢出的元素;04年P(guān)OPO就發(fā)現(xiàn)overflow:hidden會(huì)導(dǎo)致中鍵失效,這是我作為一個(gè)多標(biāo)簽瀏覽控所不能接受的。所以還是不要使用了

4)父元素設(shè)置 overflow:auto 屬性

同樣IE6需要觸發(fā)hasLayout,演示和3差不多

優(yōu)點(diǎn):不存在結(jié)構(gòu)和語(yǔ)義化問(wèn)題,代碼量極少

缺點(diǎn):多個(gè)嵌套后,firefox某些情況會(huì)造成內(nèi)容全選;IE中 mouseover 造成寬度改變時(shí)會(huì)出現(xiàn)最外層模塊有滾動(dòng)條等,firefox早期版本會(huì)無(wú)故產(chǎn)生focus等, 請(qǐng)看 嗷嗷的?Demo?,不要使用

5)父元素也設(shè)置浮動(dòng)

優(yōu)點(diǎn):不存在結(jié)構(gòu)和語(yǔ)義化問(wèn)題,代碼量極少

缺點(diǎn):使得與父元素相鄰的元素的布局會(huì)受到影響,不可能一直浮動(dòng)到body,不推薦使用

6)父元素設(shè)置display:table

?優(yōu)雅的 Demo

?優(yōu)點(diǎn):結(jié)構(gòu)語(yǔ)義化完全正確,代碼量極少

缺點(diǎn):盒模型屬性已經(jīng)改變,由此造成的一系列問(wèn)題,得不償失,不推薦使用

7)使用:after 偽元素

需要注意的是 :after是偽元素(Pseudo-Element),不是偽類(某些CSS手冊(cè)里面稱之為“偽對(duì)象”),很多清除浮動(dòng)大全之類的文章都稱之為偽類,不過(guò)csser要嚴(yán)謹(jǐn)一點(diǎn),這是一種態(tài)度。

由于IE6-7不支持:after,使用 zoom:1觸發(fā) 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的市場(chǎng)占有率極低,我們直接忽略掉,最后精簡(jiǎn)的代碼如下:

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

.clearfix { *zoom:1; }

?優(yōu)雅的 Demo

優(yōu)點(diǎn):結(jié)構(gòu)和語(yǔ)義化完全正確,代碼量居中

缺點(diǎn):復(fù)用方式不當(dāng)會(huì)造成代碼量增加

?小結(jié)

通過(guò)對(duì)比,我們不難發(fā)現(xiàn),其實(shí)以上列舉的方法,無(wú)非有兩類:

其一,通過(guò)在浮動(dòng)元素的末尾添加一個(gè)空元素,設(shè)置 clear:both屬性,after偽元素其實(shí)也是通過(guò) content 在元素的后面生成了內(nèi)容為一個(gè)點(diǎn)的塊級(jí)元素;

其二,通過(guò)設(shè)置父元素 overflow 或者display:table 屬性來(lái)閉合浮動(dòng),我們來(lái)探討一下這里面的原理。

在CSS2.1里面有一個(gè)很重要的概念,但是國(guó)內(nèi)的技術(shù)博客介紹到的比較少,那就是?Block formatting contexts?(塊級(jí)格式化上下文),以下簡(jiǎn)稱 BFC。

CSS3里面對(duì)這個(gè)規(guī)范做了改動(dòng),稱之為:flow root,并且對(duì)觸發(fā)條件進(jìn)行了進(jìn)一步說(shuō)明。

那么如何觸發(fā)BFC呢?

  • float 除了none以外的值?
    ?
  • overflow 除了visible 以外的值(hidden,auto,scroll )?
    ?
  • display (table-cell,table-caption,inline-block)?
    ?
  • position(absolute,fixed)?
    ?
  • fieldset元素

需要注意的是,display:table 本身并不會(huì)創(chuàng)建BFC,但是它會(huì)產(chǎn)生匿名框(anonymous boxes),而匿名框中的display:table-cell可以創(chuàng)建新的BFC,換句話說(shuō),觸發(fā)塊級(jí)格式化上下文的是匿名框,而不是 display:table。所以通過(guò)display:table和display:table-cell創(chuàng)建的BFC效果是不一樣的。

?fieldset 元素在www.w3.org里目前沒有任何有關(guān)這個(gè)觸發(fā)行為的信息,直到HTML5標(biāo)準(zhǔn)里才出現(xiàn)。有些瀏覽器bugs(Webkit,Mozilla)提到過(guò)這個(gè)觸發(fā)行為,但是沒有任何官方聲明。實(shí)際上,即使fieldset在大多數(shù)的瀏覽器上都能創(chuàng)建新的塊級(jí)格式化上下文,開發(fā)者也不應(yīng)該把這當(dāng)做是理所當(dāng)然的。CSS 2.1沒有定義哪種屬性適用于表單控件,也沒有定義如何使用CSS來(lái)給它們添加樣式。用戶代理可能會(huì)給這些屬性應(yīng)用CSS屬性,建議開發(fā)者們把這種支持當(dāng)做實(shí)驗(yàn)性質(zhì)的,更高版本的CSS可能會(huì)進(jìn)一步規(guī)范這個(gè)。

?

BFC的特性:

1)塊級(jí)格式化上下文會(huì)阻止外邊距疊加

當(dāng)兩個(gè)相鄰的塊框在同一個(gè)塊級(jí)格式化上下文中時(shí),它們之間垂直方向的外邊距會(huì)發(fā)生疊加。換句話說(shuō),如果這兩個(gè)相鄰的塊框不屬于同一個(gè)塊級(jí)格式化上下文,那么它們的外邊距就不會(huì)疊加。

2)塊級(jí)格式化上下文不會(huì)重疊浮動(dòng)元素

根據(jù)規(guī)定,一個(gè)塊級(jí)格式化上下文的邊框不能和它里面的元素的外邊距重疊。這就意味著瀏覽器將會(huì)給塊級(jí)格式化上下文創(chuàng)建隱式的外邊距來(lái)阻止它和浮動(dòng)元 素的外邊距疊加。由于這個(gè)原因,當(dāng)給一個(gè)挨著浮動(dòng)的塊級(jí)格式化上下文添加負(fù)的外邊距時(shí)將會(huì)不起作用(Webkit和IE6在這點(diǎn)上有一個(gè)問(wèn)題——可以看這 個(gè)測(cè)試用例)。?

3)塊級(jí)格式化上下文通常可以包含浮動(dòng)

詳見: W3C CSS2.1 - 10.6.7 'Auto' heights for block formatting context roots?
??

通俗地來(lái)說(shuō):創(chuàng)建了 BFC的元素就是一個(gè)獨(dú)立的盒子,里面的子元素不會(huì)在布局上影響外面的元素,反之亦然,同時(shí)BFC任然屬于文檔中的普通流。

至此,您或許明白了為什么 overflow:hidden或者auto可以閉合浮動(dòng)了,真是因?yàn)楦冈貏?chuàng)建了新的BFC。對(duì)于張?chǎng)涡裨趯?duì)《overflow與zoom”清除浮動(dòng)”的一些認(rèn)識(shí) 》一文中對(duì)于用包裹來(lái)解釋閉合浮動(dòng)的原理,我覺得是不夠嚴(yán)謹(jǐn)?shù)?#xff0c;而且沒有依據(jù)。并且說(shuō)道“Firefox等瀏覽器并沒有haslayout的概念”,那么現(xiàn)代瀏覽器是有BFC的,從表現(xiàn)上來(lái)說(shuō),hasLayout 可以等同于 BFC。

IE6-7的顯示引擎使用的是一個(gè)稱為布局(layout)的內(nèi)部概念,由于這個(gè)顯示引擎自身存在很多的缺陷,直接導(dǎo)致了IE6-7的很多顯示 bug。當(dāng)我們說(shuō)一個(gè)元素“得到 layout”,或者說(shuō)一個(gè)元素“擁有 layout” 的時(shí)候,我們的意思是指它的微軟專有屬性 hasLayout?http://msdn.microsoft.com/worksh ... rties/haslayout.asp?為此被設(shè)為了 true 。IE6-7使用布局的概念來(lái)控制元素的尺寸和定位,那些擁有布局(have layout)的元素負(fù)責(zé)本身及其子元素的尺寸設(shè)置和定位。如果一個(gè)元素的 hasLayout 為false,那么它的尺寸和位置由最近擁有布局的祖先元素控制。

觸發(fā)hasLayout的條件:

  • position: absolute?
    ?
  • float: left|right?
    ?
  • display: inline-block?
    ?
  • width: 除 “auto” 外的任意值?
    ?
  • height: 除 “auto” 外的任意值 (例如很多人清除浮動(dòng)會(huì)用到 height: 1%??)?
    ?
  • zoom: 除 “normal” 外的任意值 (MSDN)?http://msdn.microsoft.com/worksh ... properties/zoom.asp?
    ?
  • writing-mode: tb-rl (MSDN)?http://msdn.microsoft.com/worksh ... ies/writingmode.asp

在 IE7 中,overflow 也變成了一個(gè) layout 觸發(fā)器:

  • overflow: hidden|scroll|auto?( 這個(gè)屬性在IE之前版本中沒有觸發(fā) layout 的功能。?)
    ?
  • overflow-x|-y: hidden|scroll|auto?(CSS3 盒模型中的屬性,尚未得到瀏覽器的廣泛支持。他們?cè)谥癐E版本中同樣沒有觸發(fā) layout 的功能)

hasLayout更詳細(xì)的解釋請(qǐng)參見 old9翻譯的 大名鼎鼎的?《On having layout》一文(英文原文:http://www.satzansatz.de/cssd/onhavinglayout.htm),由于old9博客被墻,中文版地址:

IE8使用了全新的顯示引擎,據(jù)稱不使用 hasLayout屬性了,因此解決了很多深惡痛絕的bug。

綜上所述:

在支持BFC的瀏覽器(IE8+,firefox,chrome,safari)通過(guò)創(chuàng)建新的BFC閉合浮動(dòng);

在不支持 BFC的瀏覽器 (IE6-7),通過(guò)觸發(fā) hasLayout 閉合浮動(dòng)。

?

四、閉合浮動(dòng)方法——精益求精

上面已經(jīng)列舉了7種閉合浮動(dòng)的方法,通過(guò)第三節(jié)分析的原理,我們發(fā)現(xiàn)其實(shí)更多的:display:table- cell,display:inline-block等只要觸發(fā)了BFC的屬性值都可以閉合浮動(dòng)。從各個(gè)方面比較,after偽元素閉合浮動(dòng)無(wú)疑是相對(duì)比 較好的解決方案了,下面詳細(xì)說(shuō)說(shuō)該方法。

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

.clearfix { *zoom:1; }

1) display:block 使生成的元素以塊級(jí)元素顯示,占滿剩余空間;

2) height:0 避免生成內(nèi)容破壞原有布局的高度。

3) visibility:hidden?使生成的內(nèi)容不可見,并允許可能被生成內(nèi)容蓋住的內(nèi)容可以進(jìn)行點(diǎn)擊和交互;

4)通過(guò) content:"."生成內(nèi)容作為最后一個(gè)元素,至于content里面是點(diǎn)還是其他都是可以的,例如oocss里面就有經(jīng)典的 content:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",有些版本可能content 里面內(nèi)容為空,一絲冰涼是不推薦這樣做的,firefox直到7.0?content:”" 仍然會(huì)產(chǎn)生額外的空隙;

5)zoom:1 觸發(fā)IE hasLayout。

通過(guò)分析發(fā)現(xiàn),除了clear:both用來(lái)清除浮動(dòng)的,其他代碼無(wú)非都是為了隱藏掉content生成的內(nèi)容,這也就是其他版本的閉合浮動(dòng)為什么會(huì)有font-size:0,line-height:0。

?

精益求精方案一:

相對(duì)于空標(biāo)簽閉合浮動(dòng)的方法代碼似乎還是有些冗余,通過(guò)查詢發(fā)現(xiàn)Unicode字符里有一個(gè)“零寬度空格”,也就是U+200B?,這個(gè)字符本身是不可見的,所以我們完全可以省略掉 visibility:hidden了

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

.clearfix { *zoom:1; }.

精益求精方案二:

由Nicolas Gallagher 大濕提出來(lái)的,原文:A new micro clearfix hack,該方法也不存在firefox中空隙的問(wèn)題。

/* For modern browsers */

.cf:before,.cf:after {

content:"";

display:table;

}

.cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */

.cf { zoom:1; }

?需要注意的是:

上面的方法用到了? :before偽元素,很多人對(duì)這個(gè)有些迷惑,到底我什么時(shí)候需要用before呢?為什么方案一沒有呢?其實(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)該有的特性。

請(qǐng)看優(yōu)雅的Demo

進(jìn)一步了解請(qǐng)看:?《clearfix改良及overflow:hidden詳解【譯】》

在實(shí)際開發(fā)中,改進(jìn)方案一由于存在Unicode字符不適合內(nèi)嵌CSS的GB2312編碼的頁(yè)面,使用方案7完全可以解決我們的需求了,改進(jìn)方案二 等待大家的進(jìn)一步實(shí)踐。方案3、4通過(guò)overflow閉合浮動(dòng),實(shí)際上已經(jīng)創(chuàng)建了新的 塊級(jí)格式化上下文,這將導(dǎo)致其布局和相對(duì)于浮動(dòng)的行為等發(fā)生一系列的變化,清除浮動(dòng)只不過(guò)是一系列變化中的一個(gè)作用而已。所以為了閉合浮動(dòng)去改變?nèi)痔?性,這是不明智的,帶來(lái)的風(fēng)險(xiǎn)就是一系列的bug,比如firefox 早期版本產(chǎn)生 focus,截?cái)嘟^對(duì)定位的層等等。始終要明白,如果單單只是需要閉合浮動(dòng),overflow就不要使用,而不是某些文章所說(shuō)的“慎用”。

前前后后花了三天寫完了這篇文章。如果覺得本文對(duì)您有幫助,您的留言就是對(duì)我最大的支持,同時(shí)由于精力有限,歡迎指出文中錯(cuò)誤與不足,共勉之!

參考資料:

?

  • Page breaks and block-formatting contexts:?Allowed page breaks (13.3.3)
  • Clearfix and block formatting contexts:?Everything you Know about Clearfix is Wrong
  • Block formating contexts, “hasLayout” – IE Window vs CSS2.1 browsers: simulations.
  • New block formatting contexts next to floats
  • Control Block Formatting Context
    • On having layout, [譯文]On having layout ?http://old9.blogsome.com/2006/04/11/onhavinglayout
    • “HasLayout” Overview
    • hasLayout Property
    • IE hasLayout
    • https://developer.mozilla.org/en/CSS/block_formatting_context

總結(jié)

以上是生活随笔為你收集整理的(转)那些年我们一起清除过的浮动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。