在解釋BFC之前,先說一下文檔流。我們常說的文檔流其實分為定位流、浮動流、普通流三種。而普通流其實就是指BFC中的FC。FC(Formatting Context),直譯過來是格式化上下文,它是頁面中的一塊渲染區(qū)域,有一套渲染規(guī)則,決定了其子元素如何布局,以及和其他元素之間的關系和作用。常見的FC有BFC、IFC,還有GFC和FFC。
BFC(Block Formatting Context)塊級格式化上下文,是用于布局塊級盒子的一塊渲染區(qū)域,或者說是在一定條件下的一種渲染規(guī)則。
MDN上的解釋:BFC是Web頁面的可視化CSS渲染的部分,是塊級盒布局發(fā)生的區(qū)域,也是浮動元素與其他元素交互的區(qū)域。
根元素,即HTML標簽
float的值不為 none,為 left
、right
overflow值不為 visible,為 auto
、scroll
、hidden
display值為 inline-block
、table-cell
、table-caption
、flex
、inline-flex
、grid
、inline-grid
position值為 absolute
、fixed
注意:display:table也可以生成BFC的原因在于Table會默認生成一個匿名的table-cell,是這個匿名的table-ccell生成了BFC。
瀏覽器對BFC區(qū)域的約束規(guī)則:
生成BFC元素的子元素會一個接一個的放置。垂直方向上他們的起點是一個包含塊的頂部,兩個相鄰子元素之間的垂直距離取決于元素的margin特性。在BFC中相鄰的塊級元素的外邊距會折疊(Mastering margin collapsing)。
生成BFC元素的子元素中,每一個子元素左外邊距與包含塊的左邊界相接觸(對于從右到左的格式化,右外邊距接觸右邊界),即使浮動元素也是如此(盡管子元素的內(nèi)容區(qū)域會由于浮動而壓縮),除非這個子元素也創(chuàng)建了一個新的BFC(如它自身也是一個浮動元素)。
規(guī)則解讀:
內(nèi)部的Box會在垂直方向上一個接一個的放置
內(nèi)部的Box垂直方向上的距離由margin決定。(完整的說法是:屬于同一個BFC的兩個相鄰Box的margin會發(fā)生折疊,不同BFC不會發(fā)生折疊。)
每個元素的左外邊距與包含塊的左邊界相接觸(從左向右),即使浮動元素也是如此。(這說明BFC中子元素不會超出他的包含塊,而position為absolute的元素可以超出他的包含塊邊界)
BFC的區(qū)域不會與float的元素區(qū)域重疊
計算BFC的高度時,浮動子元素也參與計算
BFC是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面元素,反之亦然。我們可以利用BFC的這個特性來做很多事。
一個正常文檔流的block元素可能被一個float元素覆蓋,擠占正常文檔流,因此可以設置一個元素的float、display、position值等方式觸發(fā)BFC,以阻止被浮動盒子覆蓋。
查看DEMO
通過改變包含浮動子元素的父盒子的屬性值,觸發(fā)BFC,以此來包含子元素的浮動盒子。
查看DEMO
屬于同一個BFC的兩個相鄰塊級子元素的上下margin會發(fā)生重疊,(設置writing-mode:tb-rl時,水平margin會發(fā)生重疊)。所以當兩個相鄰塊級子元素分屬于不同的BFC時可以阻止margin重疊。
這里給任一個相鄰塊級盒子的外面包一個p,通過改變此p的屬性使兩個原盒子分屬于兩個不同的BFC,以此來阻止margin重疊。
查看DEMO
但是這里有個疑問:
如果外面包一層p,設置能觸發(fā)BFC的任何屬性都能阻止相鄰元素的margin合并。因為分屬不同BFC不會發(fā)生margin合并。
而如果在外面不包一個p的話,當設置display為inline-block、inline-flex、table-captain,和position為absolute、fixed,float為left、right是可以阻止margin合并的。這里問題來了:
我們知道設置position和float會讓元素脫離文檔流并且又創(chuàng)建新的BFC,所以兩個元素就不是相鄰元素了,因此可以阻止相鄰元素margin合并,但是inline-block、inline-flex、inline-grid、table-captain為什么可以呢?如果有人知道為什么,請告知~
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com