今天給你們說說BFC這個概念,在說概念前,先給你們看個例子:html
首先,定義三個div塊元素佈局
效果:flex
咱們發現,塊級元素的排列順序是從上往下,一塊接着一塊,在w3c中,是這樣解釋block-level box的:spa
在一個塊級排版上下文中,盒子是從包含塊頂部開始,垂直的一個接一個的排列的。3d
相鄰兩個盒子之間的垂直的間距是被margin屬性所決定的,在一個塊級排版上下文中相鄰的兩個塊級盒之間的垂直margin是摺疊的code
我們看個例子:orm
代碼以下:htm
在圖中咱們發現,在給兩個塊級元素設置一樣的margin-bottom值時,他們之間會發生margin摺疊blog
觀察此圖,你會發現 class爲 d1的塊元素的margin已經與 d2塊元素的margin產生摺疊 文檔
在d2與d3中,也發生摺疊現象,d3margin-top設置爲60px,d2margin-bottom設置爲50px,因此多了10px
好了,既然咱們發現這種摺疊的現象,咱們就思考,怎麼解決這種問題?
好,今天的主角登場:BFC
1、BFC概念:
Block Formatting Contexts 即塊級格式化上下文,其中 Formatting Context 是一個決定如何渲染文檔的容器
Formatting context是W3C CSS2.1規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。
最多見的Formatting context有Block fomatting context(BFC)和Inline formatting context(IFC)。CSS2.1 中只有BFC和IFC, CSS3中還增長了GFC和FFC。
上面是來自w3c的對於BFC的概念,下面說說具體:
建立的BFC元素就是一個獨立的盒子(見右下方圖),只有Blcok-level box(塊級盒) 能夠建立BFC,它規定了內部的Block-level Box如何佈局,而且與這個獨立盒子裏的佈局不受外部影響,固然它也不會影響到外面的元素。圖中margin、border、padding、content分別定義了元素四種邊,而後每種類型的邊的四條邊定義了一個盒子,分別是content box、padding box、border box、margin box,而決定塊盒在包含塊中與相鄰塊盒的垂直間距的即是margin-box,這個margin-box是始終存在的,即便它的margin爲0
好的,概念我們說完了,看到這裏,是否是有些懵?不要緊,接下來先說說BFC的特性吧:
2、BFC特性:
1.內部的box會在垂直方向,從頂部開始一個接着一個地放置
2.box 垂直方向的距離由margin(外邊距)決定。屬於同一個BFC的兩個相鄰box的margin會發生疊加(例子所提到的盒子margin合併問題)
3.BFC的區域不會與float box疊加
4.BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然
5.計算BFC高度時,浮動元素也參與計算
6.每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。(看應用例子2)
那麼咱們怎樣才能觸發BFC呢?
3、觸發BFC:
1.設置除 float:none 之外的屬性值(如:left | right)就會觸發BFC
2.設置除 overflow: visible 之外的屬性值(如: hidden | auto | scroll)就會觸發BFC
3.設置 display屬性值爲: inline-block | flex | inline-flex | table-cell | table-caption 就會觸發BFC
4.設置 position 屬性值爲:absolute | fixed 就會觸發BFC
5.使用 fieldset 元素(能夠給表單元素設置環繞邊框的html元素)也會觸發BFC
好了,觸發BFC的方法我們說完了,那如今我們來講說BFC有哪些運用吧:
4、應用BFC:
1.解決margin疊加問題
這裏給出例子:
咱們給例子中d1設置一個display:inline-block屬性
效果:
此時,因爲d1塊元素經過display:inline-block觸發了BFC,使得margin摺疊得以解決,因此,此時的d1的margin-bottom,與d2的margin-top就不會發生摺疊了。
2.用於佈局
這裏給出一個有缺陷的自適應兩欄佈局的例子:
先給出代碼:
咱們給d1設置了float: left 屬性,則d1會觸發BFC,咱們看下圖效果:
在圖中咱們發現因爲d1觸發BFC,d2將d1包含,即d2元素的margin-box的左邊, 與包含塊d1的border box的左邊相接觸(符合從左向右的格式化)。即便存在浮動float:left也是如此。
那麼,並無達到咱們想要的兩欄佈局需求(在d1下多了d2的一部分),那如今咱們怎麼解決這個問題?
先上代碼:
這裏咱們給d2元素設置了overflow屬性,讓其也觸發BFC,這樣,將d1與d2變成了兩個相互隔離的獨立盒子,此時這兩個獨立盒子裏的佈局不受外部影響,也不會影響到外面的元素
咱們看效果:
此時這個效果就是咱們想要的兩欄佈局效果了,這就是利用了BFC進行佈局的一個實例,記住!觸發BFC的元素會變成一個獨立的盒子,這個獨立盒子裏的佈局不受外部影響,也不會影響到外面的元素!這就是BFC的精髓所在!
3.用於清除浮動,計算BFC高度
BFC還能夠用於清除浮動,具體先上代碼:
效果:
在這裏咱們給父元素設置了一個border,咱們想讓父元素包裹住d1,但是當d1設置float屬性後(即觸發BFC),咱們發現,父元素沒法包裹d1了
那麼,咱們該怎麼清除由float觸發BFC帶來的問題呢?
咱們知道,在計算BFC
的高度時,浮動元素也參與計算,如今子元素d1已經觸發BFC(即成爲獨立盒子),那麼父元素是否是也能夠經過觸發BFC,在計算高度時可讓
子元素d1也實現浮動元素的高度計算呢?
咱們來試試:
咱們給父元素設置overflow:auto 屬性來觸發BFC
效果:
果真,給父元素設置BFC,確實可讓d1這個浮動元素隨父元素進行高度計算,這樣,咱們就解決了利用BFC清除浮動的問題。