CSS中有個重要的概念BFC,搞懂BFC可讓咱們理解CSS中某些本來詭異(??)的地方。css
感興趣的同窗能夠加文末的微信羣,一塊兒討論吧~html
在解釋BFC以前,先說一下文檔流。咱們常說的文檔流其實分爲定位流、浮動流、普通流三種。而普通流其實就是指BFC中的FC。FC(Formatting Context),直譯過來是格式化上下文,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其餘元素之間的關係和做用。常見的FC有BFC、IFC,還有GFC和FFC。前端
BFC(Block Formatting Context)塊級格式化上下文,是用於佈局塊級盒子的一塊渲染區域。MDN上的解釋:BFC是Web頁面 CSS 視覺渲染的一部分,用於決定塊盒子的佈局及浮動相互影響範圍的一個區域。web
注意:一個BFC的範圍包含建立該上下文元素的全部子元素,但不包括建立了新BFC的子元素的內部元素。這從另外一方角度說明,一個元素不能同時存在於兩個BFC中。由於若是一個元素可以同時處於兩個BFC中,那麼就意味着這個元素能與兩個BFC中的元素髮生做用,就違反了BFC的隔離做用。segmentfault
常規流(Normal flow)瀏覽器
浮動(Floats)微信
絕對定位(Absolute positioning)ide
left
、right
auto
、scroll
、hidden
inline-block
、table-cell
、table-caption
、table
、inline-table
、flex
、inline-flex
、grid
、inline-grid
absolute
、fixed
注意 display:table也能夠生成BFC的緣由在於Table會默認生成一個匿名的table-cell,是這個匿名的table-cell生成了BFC。佈局
瀏覽器對BFC區域的約束規則:學習
規則解讀:
BFC是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素,反之亦然。咱們能夠利用BFC的這個特性來作不少事。
一個正常文檔流的block元素可能被一個float元素覆蓋,擠佔正常文檔流,所以能夠設置一個元素的float、display、position值等方式觸發BFC,以阻止被浮動盒子覆蓋。
經過改變包含浮動子元素的父盒子的屬性值,觸發BFC,以此來包含子元素的浮動盒子。
注意,這裏觸發BFC並不能阻止其它形式的脫離文檔流的元素覆蓋正常流元素。
BFC內部其餘形式脫離文檔流(absolute fixed)
有時候由於多列布局採用小數點位的width致使由於瀏覽器由於四捨五入形成的換行的狀況,能夠在最後一列觸發BFC的形式來阻止換行的發生。好比下面栗子的特殊狀況
屬於同一個BFC的兩個相鄰塊級子元素的上下margin會發生重疊,(設置writing-mode:tb-rl時,水平margin會發生重疊)。因此當兩個相鄰塊級子元素分屬於不一樣的BFC時能夠阻止margin重疊。 這裏給任一個相鄰塊級盒子的外面包一個div,經過改變此div的屬性使兩個原盒子分屬於兩個不一樣的BFC,以此來阻止margin重疊。
可是這裏有個疑問: 若是外面包一層div,設置能觸發BFC的任何屬性都能阻止相鄰元素的margin合併。由於分屬不一樣BFC不會發生margin合併。 而若是在外面不包一個div的話,當設置display爲inline-block、inline-flex、table-captain,和position爲absolute、fixed,float爲left、right是能夠阻止margin合併的。這裏問題來了:
咱們知道設置position和float會讓元素脫離文檔流而且又建立新的BFC,因此兩個元素就不是相鄰元素了,所以能夠阻止相鄰元素margin合併,可是inline-block、inline-flex、inline-grid、table-captain爲何能夠呢?若是有人知道爲何,請告知~
網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~
參考:
PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~
另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~