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