理解BFC

理解BFC

更好閱讀體驗移步:http://zhangzippo.github.io/posts/2019/04/28/_28理解bfc.html

BFC(格式化上下文)在整個css體系中是比較重要的概念餐禁,也牽扯了很多其他問題比如如浮動、定位、盒模型等曲稼,這篇文章主要幫助理解bfc的概念礼搁,特性和應用場景闸英。

概念

先看一段來自MDN的定義:

塊格式化上下文(Block Formatting Context朗徊,BFC) 是Web頁面的可視化CSS渲染的一部分濒旦,是塊盒子的布局過程發(fā)生的區(qū)域纫谅,也是浮動元素與其他元素交互的區(qū)域炫贤。

嗯,非常嚴謹且官方(就是看不懂)那么我嘗試用一種便于理解的方式來解釋這個BFC付秕,你可以簡單的理解BFC就是頁面上的一塊兒區(qū)域兰珍,這個區(qū)域有一些特性,并且該區(qū)域內部有一套自己的規(guī)則不對外界元素產生干擾询吴,是一塊相對獨立的渲染區(qū)域掠河。(注意,參與BFC的是塊盒子)

參考其他博客中我認為最貼切的解釋:
塊格式上下文是頁面CSS 視覺渲染的一部分猛计,用于決定塊盒子的布局及浮動相互影響范圍的一個區(qū)域唠摹。

產生這塊區(qū)域需要滿足以下幾種條件:

  • 根元素或包含根元素的元素
  • 浮動元素(元素的 float 不是 none
  • 絕對定位元素(元素的 positionabsolutefixed
  • 行內塊元素(元素的 displayinline-block
  • overflow 值不為 visible 的塊元素
  • display 值為 flow-root 的元素
  • 表格單元格(元素的 displaytable-cell,HTML表格單元格默認為該值)
  • 表格標題(元素的 displaytable-caption奉瘤,HTML表格標題默認為該值)
  • 匿名表格單元格元素(元素的 displaytable勾拉、table-rowtable-row-group盗温、table-header-group藕赞、table-footer-group(分別是HTML table琉挖、row赃额、tbody匙头、thead刻蟹、tfoot的默認屬性)或 inline-table
  • contain值為 layout弄喘、contentstrict 的元素
  • 彈性元素(displayflexinline-flex元素的直接子元素)
  • 網格元素(displaygridinline-grid 元素的直接子元素)
  • 多列容器(元素的 column-count不為 auto涩赢,包括 column-count1
  • column-spanall 的元素始終會創(chuàng)建一個新的BFC押蚤,即使該元素沒有包裹在一個多列容器中耳舅。

可以看出有很多觸發(fā)BFC區(qū)域的條件蟹演,其中前幾個斜粗體的描述是我們經常遇到也需要重點記住的风钻,后面的幾種可以當作擴展了解就好。

這里重點說一下display:flow-root,display:flow-root是什么意思呢酒请?它可以創(chuàng)建無副作用的BFC骡技。在父級塊中使用 display: flow-root 可以創(chuàng)建新的BFC。我們剛才分析了上面幾種創(chuàng)造bfc的方式,但他們都是有副作用的(比如float會讓元素脫離文檔流靠左或靠右布朦,position的絕對定位也會脫離文檔流囤萤,overflow的值也會造成一些額外的影響),而這個值的設定是單純創(chuàng)造一個BFC,沒有任何其他影響是趴,但是這個屬性目前瀏覽器支持的不是很好涛舍,下圖是這個值的兼容情況:


display: flow-root兼容情況

影響的范圍

這里引用MDN的解釋:

塊格式化上下文包含創(chuàng)建它的元素內部的所有內容,但不包括創(chuàng)建了新BFC的子元素的內部元素。
塊格式化上下文對浮動定位與清除浮動都很重要唆途。浮動定位和清除浮動時只會應用于同一個BFC內的元素富雅。浮動不會影響其它BFC中元素的布局,而清除浮動只能清除同一BFC中在它前面的元素的浮動肛搬。外邊距折疊也只會發(fā)生在屬于同一BFC的塊級元素之間没佑。
這段話的重點在于1:BFC將影響內部包含的所有內容,除非內部創(chuàng)建了新的子BFC區(qū)域温赔;2:所有的BFC影響只會發(fā)生在同級次的BFC區(qū)域中蛤奢。

如下面的代碼,box創(chuàng)建了一個BFC區(qū)域陶贼,那么將影響son_1,son_1-1,son_2,由于son_自己創(chuàng)建了一個BFC區(qū)域啤贩,因此son_2-1將不受box的BFC影響,而只受son_2的BFC影響

<div id='box' class='BFC'>
    <div id='son_1'>
        <div id='son_1-1'></div>
    </div>
    <div id='son_2' class='BFC'>
        <div id='son_2-1'></div>
    </div>
</div>

從下圖我門可以看到拜秧,外層盒子創(chuàng)造了一塊兒BFC區(qū)域會清除浮動痹屹,第一層因為浮動的關系撐開了外層盒子,由于float:left創(chuàng)造了一塊兒新的BFC區(qū)域枉氮,因此它的子元素的float不會撐開最外層痢掠,因此沒有受到最外層BFC的影響(沒有撐開第二層因為第二層給了固定高度)。這更佳說明了BFC是一塊獨立區(qū)域嘲恍,并且內部不會影響B(tài)FC外部元素的特性足画。


BFC的影響范圍

特性

關于以下特性介紹在css2.1規(guī)范的文檔中(文章結尾文獻)有相關介紹,這里前幾條是翻譯過來講佃牛,后面幾條是來自其他文章的總結淹辞。

特性1:在BFC中,內部塊(block塊級元素)從頂部開始依次垂直排列俘侠。兩個同級塊之間的垂直距離由“Margin”屬性確定象缀。

這個特性沒什么說的,就是在BFC區(qū)域內部的子塊級元素會垂直排列爷速,這點即使不在BFC內其實也是一樣的央星,多個div會在容器內部垂直的一個一個排列。

特性2: 內部塊垂直方向的距離由margin決定惫东。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊莉给。

這個特性是指相鄰的兩個子塊元素的相隔距離由margin決定毙石,但并不是margin的和,而是會重疊(實際就是是margin之間的最大值)颓遏,如下代碼:

<div class="box">
    <div class="son">
        I am one
    </div>
    <div class="son">
        I am two
    </div>
    <div class="son">
        I am three
     </div>
</div>
<style>
.box {
  background-color: rgb(224, 206, 247);
  display:flow-root; // 創(chuàng)造一個BFC區(qū)域
  width:100%;
}
.son {
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
  margin:10px 0;
}
.son:last-child{
margin:20px 0;
}
</style>

效果如下:


image.png

可以看到每個元素之間的margin是10像素徐矩,而最后一個box與上方的box之間是20,因為margin的重疊導致了取的是兩個相鄰box的最大值叁幢。

特性3:每個子塊元素的左外邊緣接觸包含塊的左邊緣(對于從右到左的格式滤灯,右邊緣接觸)。即使在存在浮動的情況下也是如此曼玩。

這里解釋一下鳞骤,我們知道每一個box模型是由四個層級構成的,如圖:


image.png

從外到內分別是margin-box黍判,border-box弟孟,padding-box和content-box,這個規(guī)則的意思就是說我們的子塊的外邊緣(也就是margin-box邊緣)會與BFC區(qū)域的邊緣(也就是content-box的邊緣)样悟,即使在子塊存在浮動的情況下也是一樣的。

.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
  display:flow-root;
padding: 10px;
}
.float {
  float:left; // 添加浮動
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  margin:0 10px;
}

內部元素有一個10像素的margin,外部盒子有10像素的padding庭猩,內部元素的margin-box的左邊與包含塊content-box的做邊緣接觸


特性3

特性4:BFC就是頁面上的一個隔離的獨立容器窟她,容器里面的子元素不會影響到外面的元素,反之亦然蔼水;
這點在上面我們介紹影響范圍的時候介紹過震糖,不再做過多說明了。

特性5:計算BFC的高度時趴腋,考慮BFC所包含的所有元素吊说,連浮動元素也參與計算
這個特性就是為何子元素浮動,如果要清除浮動可以在父元素上創(chuàng)造一個bfc的解釋优炬,這樣高度就囊括了浮動元素颁井。
特性6:浮動盒區(qū)域不疊加到BFC上

<div class="box"></div>
<div class="float"></div>
<style>
  .box { 
    background-color: rgb(224, 206, 247); 
    border: 5px solid rebeccapurple;
    height:100px; 
    width:100px;
    padding:10px; display:flow-root; 
  }
  .float { 
    float:left;
    height: 150px;
    background-color: white; 
    border: 1px solid black; 
    padding: 10px; 
  } 
</style>
可以看到浮動元素沒有覆蓋到bfc上面
浮動盒區(qū)域不疊加到BFC上

應用

1. 分屬于不同的BFC時可以阻止margin重疊
根據特性2我們知道,BFC內的元素排列時margin會重疊蠢护,因此我們?yōu)榱朔乐怪丿B雅宾,可以使兩個元素創(chuàng)建自己的bfc,這樣margin就不會重疊葵硕。
2. 可以包含浮動元素——清除內部浮動
根據特性五可以得知眉抬。
3. 可以阻止元素被浮動元素覆蓋
根據特性六,只需要將被覆蓋的元素創(chuàng)建成為BFC就可以解決這個問題懈凹。
4. 自適應兩欄布局
我們可以利用bfc的特性來構造兩欄布局:

<div class="left"></div>
<div class="right"></div>
<style>
  .left{
background:yellow;
width:200px;
height:400px;
float:left;
}
.right{
background:pink;
height:400px;
/*添加overflow:hidden蜀变,觸發(fā)元素BFC*/
overflow:hidden;
}
</style>
右側自適應兩欄布局

當然我們也可以利用該特性進行3欄的布局,道理都是一樣的介评。

這篇文章對BFC的前置概念沒有過多說明库北,比如盒模型以及定位方案等,可以查看https://juejin.im/post/59b73d5bf265da064618731d這篇文章,本篇文章也部分參考了該文章贤惯。

參考文獻

https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
https://www.w3.org/TR/CSS21/visuren.html#block-formatting
https://juejin.im/post/59b73d5bf265da064618731d

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末洼专,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子孵构,更是在濱河造成了極大的恐慌屁商,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颈墅,死亡現場離奇詭異蜡镶,居然都是意外死亡,警方通過查閱死者的電腦和手機恤筛,發(fā)現死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門官还,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人毒坛,你說我怎么就攤上這事望伦。” “怎么了煎殷?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵屯伞,是天一觀的道長。 經常有香客問我豪直,道長劣摇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任弓乙,我火速辦了婚禮末融,結果婚禮上,老公的妹妹穿的比我還像新娘暇韧。我一直安慰自己勾习,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布懈玻。 她就那樣靜靜地躺著语卤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酪刀。 梳的紋絲不亂的頭發(fā)上粹舵,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音骂倘,去河邊找鬼眼滤。 笑死,一個胖子當著我的面吹牛历涝,可吹牛的內容都是我干的诅需。 我是一名探鬼主播漾唉,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼堰塌!你這毒婦竟也來了赵刑?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤场刑,失蹤者是張志新(化名)和其女友劉穎般此,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體牵现,經...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡铐懊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了瞎疼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片科乎。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贼急,靈堂內的尸體忽然破棺而出茅茂,到底是詐尸還是另有隱情,我是刑警寧澤太抓,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布空闲,位于F島的核電站,受9級特大地震影響腻异,放射性物質發(fā)生泄漏。R本人自食惡果不足惜这揣,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一悔常、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧给赞,春花似錦机打、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柑蛇,卻和暖如春芥挣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耻台。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工空免, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盆耽。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓蹋砚,卻偏偏與公主長得像扼菠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子坝咐,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案循榆? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,754評論 1 92
  • BFC 的全稱是 Block Formating Context,譯為“塊級格式化上下文”墨坚,是 CSS 規(guī)范中的一...
    柏丘君閱讀 317評論 0 0
  • 深入理解BFC與IFC 正常的流中就是如何把文檔中的元素呈現出來 秧饮,而布局呈現的規(guī)則就是BFC、IFC和相對位移框杜,...
    moyi_gg閱讀 4,959評論 2 1
  • 一浦楣、什么是BFC Formatting context 是 W3C CSS2.1 規(guī)范中的一個概念。它是頁面中的一...
    浪里行舟閱讀 657評論 0 3
  • 本來是計劃重讀李笑來的專欄,但是在閱讀過程中油狂,我發(fā)現自己一個很大的問題:一字不落的讀完后历恐,發(fā)覺自己的大腦沒怎么吸收...
    陽光小鹿530閱讀 253評論 0 3