浮動是什么:
浮動:浮動元素會脫離文檔流并向左右移動,直到碰到父元素或者另一個浮動元素。
浮動元素不屬于文檔中的普通流,當一個元素浮動之后,不會影響到塊級元素的布局而只會影響內(nèi)聯(lián)元素(通常是文本)的排列,文檔中的普通流就會表現(xiàn)的和浮動元素不存在一樣,當浮動元素高度超出包含框的時候,也就會出現(xiàn)父級元素不會自動升高來閉合元素(高度塌陷)。
正是因為浮動的這種特性,導致本屬于普通流中的元素浮動之后,包含框內(nèi)部由于不存在其他普通流元素了,也就表現(xiàn)出高度為0(高度塌陷)。在實際布局中,往往這并不是我們所希望的,所以需要閉合浮動元素,使其包含框表現(xiàn)出正常的高度。
清除浮動的原因:
1 影響別的元素的布局
2 造成高度塌陷
清除浮動的方法
方法一(差):添加額外標簽
使用帶有clear屬性的空元素
<div class="container">
<div class="floatLeft"></div>
<div class="floatRight"></div>
<div class="clear"></div>
</div>
.clear{clear:both;}
優(yōu)點:通俗易懂,容易掌握
缺點:將添加很多無意義的空標簽,有違結構與表現(xiàn)的分離,后期維護會是噩夢。
方法二(差):使用br標簽及自身html屬性
這個方法有些小眾,br 有clear="all | left | right | none"屬性
<div class="container">
<div class="floatLeft"></div>
<div class="floatRight"></div>
<br clear="all">
</div>
優(yōu)點:比空標簽方式語義強,代碼量較少
缺點:同樣有違結構與表現(xiàn)的分離,不推薦使用
方法三(差):父元素設置overflow 屬性
通過設置父元素overflow值設置為hidden;在IE6中還需要出發(fā)hasLayout,例如zoom:1;
<div class="container">
<div class="floatLeft"></div>
<div class="floatRight"></div>
</div>
.container{
overflow:hidden;
*zoom:1;
}
優(yōu)點:不存在結構和語義化問題,代碼量較少
缺點:overflow:hidden; 可能會隱藏掉不想被隱藏掉的東西。
方法四(差):父元素設置display: table
<div class="container">
<div class="floatLeft"></div>
<div class="floatRight"></div>
</div>
.container{
display:table;
}
優(yōu)點:結構語義化完全正確,代碼量極少
缺點:盒模型屬性已經(jīng)改變,由此造成了一系列問題
方法五(可):使用:after偽元素
:after 偽元素在元素之后添加內(nèi)容
IE6-7不支持:after, 使用zoom:1觸發(fā)hasLayout
<div class="container clearfix">
<div class="floatLeft"></div>
<div class="floatRight"></div>
<div class="clear"></div>
</div>
.clearfix:after{
content:"\200B";
display:block;
height:0;
clear:both;
visibility:hidden;
}
.clearfix{zoom:1;}
- display:block 使生成的元素以塊級元素顯示,占滿剩余空間
2)height:0 避免生成內(nèi)容破壞原有布局的高度
3)visibility:hidden 使生成的內(nèi)容不可見,并允許可能被生成內(nèi)容蓋住的內(nèi)容可以進行點擊和交;
4)content:"" 生成內(nèi)容作為最后一個元素,至于content里面是點還是其他都可以
5)zoom:1 觸發(fā)IE hasLayout
分析:除了clear:both用來閉合浮動,其他代碼無非都是為了隱藏掉content生成的內(nèi)容,這也就是其他版本的閉合浮動為什么會有font-size:0, line-height: 0;
優(yōu)化升級版本(可):
.clearfix:before, .clearfix:after{
content: "";
display:table;
}
.clearfix:after{
clearfix:both;
}
.clearfix{
*zoom:1; 兼容IE6,7
}
清除浮動的原理
以上方法,分為2類:
第一類:在浮動元素末尾添加一個空元素(一 二 五)
第二類:設置父元素overflow 或者 display:table 來閉合浮動 (三 四)
為什么設置父元素overflow 或者 display:table 可以閉合浮動?
其原理:Block formatting contexts(塊級格式化上下文),簡稱BFC
如何觸發(fā)BFC:
1 float 除了none以外的值
2 overflow 除了visible 以外的值(hidden,auto,scroll )
3 display (table-cell,table-caption,inline-block)
4 position(absolute,fixed)
5 fieldset元素
需要注意的是,display:table 本身并不會創(chuàng)建BFC,但是它會產(chǎn)生匿名框(anonymous boxes),而匿名框中的display:table-cell可以創(chuàng)建新的BFC,換句話說,觸發(fā)塊級格式化上下文的是匿名框,而不是display:table。所以通過display:table和display:table-cell創(chuàng)建的BFC效果是不一樣的。fieldset 元素在www.w3.org里目前沒有任何有關這個觸發(fā)行為的信息,直到HTML5標準里才出現(xiàn)。有些瀏覽器bugs(Webkit,Mozilla)提到過這個觸發(fā)行為,但是沒有任何官方聲明。實際上,即使fieldset在大多數(shù)的瀏覽器上都能創(chuàng)建新的塊級格式化上下文,開發(fā)者也不應該把這當做是理所當然的。CSS 2.1沒有定義哪種屬性適用于表單控件,也沒有定義如何使用CSS來給它們添加樣式。用戶代理可能會給這些屬性應用CSS屬性,建議開發(fā)者們把這種支持當做實驗性質(zhì)的,更高版本的CSS可能會進一步規(guī)范這個。
BFC的特性:
塊級格式化上下文會阻止外邊距疊加當兩個相鄰的塊框在同一個塊級格式化上下文中時,它們之間垂直方向的外邊距會發(fā)生疊加。換句話說,如果這兩個相鄰的塊框不屬于同一個塊級格式化上下文,那么它們的外邊距就不會疊加。
塊級格式化上下文不會重疊浮動元素根據(jù)規(guī)定,一個塊級格式化上下文的邊框不能和它里面的元素的外邊距重疊。這就意味著瀏覽器將會給塊級格式化上下文創(chuàng)建隱式的外邊距來阻止它和浮動元素的外邊距疊加。由于這個原因,當給一個挨著浮動的塊級格式化上下文添加負的外邊距時將會不起作用(Webkit和IE6在這點上有一個問題——可以看這個測試用例)。
塊級格式化上下文通??梢园釉斠姡?W3C CSS2.1 - 10.6.7 ‘Auto’ heights for block formatting context roots
通俗地來說:創(chuàng)建了 BFC的元素就是一個獨立的盒子,里面的子元素不會在布局上影響外面的元素,反之亦然,同時BFC任然屬于文檔中的普通流。overflow:hidden或者auto可以閉合浮動,就是因為父元素創(chuàng)建了新的BFC。