BFC与合并 浅析
BFC
BFC 全稱 Block Formatting Context。
每個渲染區(qū)域用formatting context表示,它決定了其子元素將如何定位,以及和其他元素的關(guān)系和相互作用
在正常流中的盒子要么屬于塊級格式化上下文,要么屬于內(nèi)聯(lián)格式化上下文
BFC特性&創(chuàng)建條件
特性
——《CSS之BFC詳解?》
創(chuàng)建條件
塊格式化上下文由以下之一創(chuàng)建:
- 根元素或其它包含它的元素
- 浮動 (元素的float不是?none)
- 絕對定位的元素 (元素具有?position?為absolute或?fixed)
- 內(nèi)聯(lián)塊?inline-blocks?(元素具有display: inline-block)
- 表格單元格 (元素具有?display: table-cell,HTML表格單元格默認(rèn)屬性)
- 表格標(biāo)題 (元素具有?display: table->caption, HTML表格標(biāo)題默認(rèn)屬性)
- 塊元素具有overflow?,且值不是?visible
- display:flow-root
——MDN - 塊格式化上下文
?
BFC 可以用來做什么?
1. 解決margin重疊的問題
根據(jù)BFC的特性,同一個BFC下的兩個相鄰的盒子會出現(xiàn)垂直margin重疊的問題,這個問題會影響我們對頁面布局的控制,通常我們可以為其中一個盒子添加一個父元素,并使其觸發(fā)BFC,即可解決這個問題:
2. 浮動帶來的布局問題
根據(jù)前面其他作者總結(jié)的BFC特性的第三條和第四條,我們知道在同一個BFC下即使有元素浮動,BFC下元素的最左邊邊緣總是會與包含它的盒子左邊相接觸,那么就會出現(xiàn)浮動元素遮蓋了其他元素的情況。BFC還有一條重要特性:BFC的區(qū)域不會與float box 重疊。試想,在一個BFC,如果存在一個float元素,和一個div,浮動元素會遮蓋住div,此時,如果給這個div構(gòu)建一個新的BFC,由于BFC特性,內(nèi)外不相互影響,此時div會被float元素擠開。
比如下面這個例子,綠色盒子會因?yàn)楦诱谏w住紅色的盒子,但由于兩個盒子都在同一個BFC(body元素)下,根據(jù)BFC特性,紅色盒子會與包含塊相接,此時只要讓紅色盒子觸發(fā)BFC,我們?yōu)榧t色盒子添加一個觸發(fā)BFC的條件overflow:hidden,此時紅色盒子由于BFC的特性隔離開綠色,這樣我們就可以通過float元素的方式實(shí)現(xiàn)兩欄布局。
3. 清除浮動
這里就要說到我們常見的浮動元素引起的高度坍塌的問題。由于浮動特性,浮動元素會脫離父元素,我們是否可以通過觸發(fā)BFC來解決高度坍塌的問題呢?
根據(jù)特性的第6條,在觸發(fā)BFC后,這個盒子的高度將包含浮動元素的高度,在計算時,浮動元素會參與高度計算,我們可以理解為,當(dāng)一個父元素中包含了浮動元素,而浮動元素超出了父元素,此時我們?yōu)楦冈貏?chuàng)建BFC,那么浮動元素就會包裹進(jìn)這個BFC解決了父元素中高度塌陷的問題。
如下面的例子,div.parent包含了兩個div.child,而兩個div由于賦予了float:left使其浮動,導(dǎo)致了div.parent高度的坍塌,此時我們給div.parent添加一個overflow:hidden屬性值,使div.parent觸發(fā)BFC,由于BFC下的盒子會包含浮動元素的高度,因此盒子就被撐了起來,高度塌陷的問題也就得到了解決。
關(guān)于合并
在什么場景下會出現(xiàn)外邊距合并?
在CSS當(dāng)中,相鄰的兩個盒子(可能是兄弟關(guān)系也可能是祖先關(guān)系)的外邊距可以結(jié)合成一個單獨(dú)的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結(jié)合成的外邊距稱為折疊外邊距。
當(dāng)兩個盒子的外邊距均為正時,折疊外邊距取外邊距更大的那個;
當(dāng)兩個盒子的外邊距 均為負(fù)時,折疊外邊距取外邊距絕對值更大的那個;
當(dāng)兩個盒子的外邊距一正一負(fù)時,折疊外邊距取兩個外邊距值的和。
?
如何合并?
產(chǎn)生合并的必備條件:margin必須是鄰接的!
而根據(jù)w3c規(guī)范,兩個margin是鄰接的必須滿足以下條件:
-
1.必須是處于常規(guī)文檔流(非float和絕對定位)的塊級盒子,并且處于同一個BFC當(dāng)中。
-
2.沒有線盒,沒有空隙(clearance),沒有padding和border將他們分隔開
-
3.都屬于垂直方向上相鄰的外邊距,可以是下面任意一種情況:
-
元素的margin-bottom與其下一個常規(guī)文檔流的兄弟元素的margin-top
-
height為auto的元素的margin-bottom與其最后一個常規(guī)文檔流的子元素的margin-bottom
-
高度為0并且最小高度也為0,不包含常規(guī)文檔流的子元素,并且自身沒有建立新的BFC的元素的margin-top和margin-bottom
-
以上的條件意味著下列的規(guī)則:
-
1.創(chuàng)建了新的BFC的元素(例如浮動元素或者overflow值為visible以外的元素)與它的子元素的外邊距不會折疊
浮動元素不與任何元素的外邊距產(chǎn)生折疊(包括其父元素和子元素) -
2.絕對定位元素不與任何元素的外邊距產(chǎn)生折疊
inline-block元素不與任何元素的外邊距產(chǎn)生折疊 -
3.一個常規(guī)文檔流元素的margin-bottom與它下一個常規(guī)文檔流的兄弟元素的margin-top會產(chǎn)生折疊,除非它們之間存在間隙(clearance)。因此使用單邊margin可以預(yù)防外邊距合并現(xiàn)象。
-
4.一個常規(guī)文檔流元素的margin-top?與其第一個常規(guī)文檔流的子元素的margin-top產(chǎn)生折疊,條件為父元素不包含?padding?和?border?,子元素不包含?clearance。
-
5.一個?'height'為'auto'并且'min-height'為?'0'的常規(guī)文檔流元素的margin-bottom會與其最后一個常規(guī)文檔流子元素的margin-bottom 折疊,條件為父元素不包含?padding和?border,子元素的?margin-bottom不與包含clearance?的?margin-top?折疊。
-
6.一個不包含border-top、border-bottom、padding-top、padding-bottom的常規(guī)文檔流元素,并且其'height'為?0或'auto','min-height'為?'0',其里面也不包含行盒(line box),其自身的?margin-top和?margin-bottom?會折疊。
如何不讓相鄰元素外邊距合并?
1.可以只設(shè)置單邊邊距。
2.讓父級元素觸發(fā) BFC,就能使父級 margin 和當(dāng)前元素的 margin 不重疊。
?
父子外邊距合并的范例
示例
?
總結(jié):
CSS之BFC詳解?中講解的三個案例和上面講解的這三種情況都是關(guān)于邊距合并的方法。
但使用overflow:hidden或者其他方式或多或少會帶來一些副作用和潛在的問題,可能在頁面剛開始創(chuàng)建的時候這些問題不會完全顯現(xiàn),但是埋下禍根...
一般我們在構(gòu)造頁面的時候就盡量不用這些方式。
舉個例子,對于margin重疊的問題,我們使用margin-top就可以很好的解決。
?
參考:
- BFC 淺析
- CSS之BFC詳解
- MDN - 塊格式化上下文
轉(zhuǎn)載于:https://www.cnblogs.com/evenyao/p/9276949.html
總結(jié)
- 上一篇: Objective-C学习笔记-使用NS
- 下一篇: 汇编常用指令