BFC及其應(yīng)用

前言

本文包括以下內(nèi)容:

  • 什么是BFC
  • 如何產(chǎn)生BFC
  • BFC的特點
  • 應(yīng)用BFC

1、什么是BFC

BFC (Block formatting contexts)塊級格式化上下文旺韭,首先看一下 w3c 是如何定義BFC的(大致翻譯如下):

浮動元素,絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions)牺弹,以及overflow不為 visiable 的塊級盒子,都會為他們的內(nèi)容創(chuàng)建新的塊級格式化上下文。

在一個塊級格式化上下文中蹦骑,盒子從頂端開始垂直地一個接一個地排列,兩個盒子之間的垂直的間隙是由他們的margin 值所決定的臀防。在一個BFC中眠菇,兩個相鄰的塊級盒子的垂直外邊距會產(chǎn)生合并边败。

在塊級格式化上下文中,每一個盒子的左外邊緣(margin-left)會觸碰到容器的左邊緣(border-left)(對于從右到左的格式來說捎废,則觸碰到右邊緣)放闺,即使存在浮動也是如此,除非這個盒子創(chuàng)建一個新的塊級格式化上下文缕坎。

可以這樣理解BFC:把BFC看作一個盒子(容器),這個BFC盒子有自己獨立的布局方式篡悟,一個BFC盒子中的元素布局不受外界影響谜叹,也不會影響到外面的元素。且在一個BFC中塊盒與行盒都會垂直排列搬葬,若存在外邊距則會產(chǎn)生外邊距合并荷腊。

2、如何產(chǎn)生BFC

在怎樣的條件下會產(chǎn)生塊級格式化上下文急凰,這里引用部分 MDN關(guān)于BFC 的內(nèi)容女仰。

  • 浮動元素
  • 絕對定位的元素 (元素具有position為 absolute或 fixed)
  • 內(nèi)聯(lián)塊 inline-blocks (元素具有 display: inline-block)
  • 表格單元格 、標題(元素具有 display: table-cell抡锈、table-caption疾忍,HTML表格單元格默認屬性)
  • 塊元素具有overflow且值不是 visible的

3、BFC的特點

  1. 同屬一個BFC的內(nèi)容會發(fā)生外邊距合并(Margin Collapse)床三,兩個外邊距大致可以分為下列三種情況:
  • 外邊距均為正值一罩,取兩者中較大的數(shù)
  • 外邊距一正一負時,取兩者相加
  • 外邊距均為負時撇簿,取兩者中絕對值較大的
  1. BFC不會重疊浮動元素
  2. BFC可以包含浮動

4聂渊、應(yīng)用BFC

  • 解決外邊距合并的問題。
    同屬一個BFC的內(nèi)容會發(fā)生外邊距合并四瘫,那么汉嗽,我們可以建立新的BFC,使得它們不屬于同一個BFC時則外邊距不會發(fā)生合并找蜜。
    外邊距合并問題1

    先是相鄰的兄弟元素外邊距合并饼暑,需要先給其中的一個盒子加上一個父元素,然后給這個父元素添加overflow:hidden锹杈,這一點很重要撵孤,可以理解為這個屬性是為其中的content新創(chuàng)建一個BFC,所以一開始在創(chuàng)建這個Demo的時候 我就有類似這樣的疑問:overflow:hidden 能觸發(fā)BFC竭望,為什么不會阻止垂直外邊距疊加邪码?
    外邊距合并解決1

    其實解決外邊距合并的方法其實有很多,個人覺得用BFC并不好咬清,且麻煩闭专,需要先創(chuàng)建一個父元素(因為直接給子元素.box2設(shè)置overflow: hidden是無效的)奴潘。當我嘗試使用另外一個方法: display: inline-block創(chuàng)建BFC的時候,發(fā)現(xiàn)并不需要創(chuàng)建父元素影钉,外邊距會直接合并画髓。
    外邊距合并解決2

    這時候我就遇到了這樣一個問題: 同樣是創(chuàng)建BFC,為什么使用overflow: hidden需要創(chuàng)建父元素平委,而使用display: inline-block不需要創(chuàng)建父元素呢奈虾?
    個人理解是這樣的:這些應(yīng)用BFC的屬性,為它們的content創(chuàng)建了一個新的獨立計算區(qū)域(BFC)廉赔,在這塊新的獨立計算區(qū)域中與外面元素的外邊距不產(chǎn)生重疊肉微,而在這塊獨立計算區(qū)域之內(nèi)仍然是外邊距重疊的。
    新的獨立計算區(qū)域

    而當使用display: inline-block觸發(fā)了別的外邊距合并的條件(可能是因為 IFC)蜡塌,并非因為BFC而發(fā)生合并碉纳。在下面的參考文章鏈接中也有指出那么一點:

inline-block元素不與任何元素的外邊距產(chǎn)生折疊

還可以參照下圖,可知應(yīng)該是display: inline-block的問題使得外邊距計算直接相加馏艾,當我們再使用其它屬性劳曹,如display: table-cell的時候,仍然需要為這個元素創(chuàng)建父元素div.ct然后應(yīng)用屬性,產(chǎn)生BFC才可以生效琅摩,而直接用在相鄰元素上是無效的铁孵。

外邊距合并解決3

  • 實現(xiàn)兩欄布局 及 去除文字環(huán)繞效果
    當存在兩個相鄰的div時,它們會垂直排列房资,但當給第一個元素設(shè)置float屬性時库菲,則會發(fā)生盒子重疊。假設(shè)第一個盒子比第二個盒子大(否則覆蓋后就看不到第二個盒子)志膀。在這里會首先發(fā)現(xiàn)這個文字并不會被浮動元素遮擋(現(xiàn)在是文字較少的情況熙宇,僅4個字符),當box1大于box2時溉浙,這個文字仍然不會被遮擋而是跑到盒子的右側(cè)或下側(cè)(據(jù)box2寬高決定)烫止。

    floatBox1+ box2

    當文字較多時,所有的文字都會圍繞著box1戳稽,形成文字環(huán)繞效果馆蠕。而給box2添加overflow:hidden;時則不會再發(fā)生文字環(huán)繞。這是之前提到的BFC特性當中的一點: * BFC 不會重疊浮動元素 *惊奇,當給box2添加屬性時互躬,它就產(chǎn)生了新的BFC使得它不會再去重疊浮動的box1
    同理,當去除box2的寬度時颂郎,即可形成自適應(yīng)的兩欄布局吼渡。
    去除文字環(huán)繞效果

  • 解決因為子元素浮動而帶來的父容器高度塌陷問題
    當一個父容器中的元素都設(shè)置為浮動,且自身沒有設(shè)置高度時乓序,則父容器的高度就會發(fā)生塌陷(就好像沒有了子元素一樣)寺酪。如下圖中的 ① 過程坎背。而給父元素設(shè)置了overflow: hidden;時則又發(fā)生了 ② 過程這樣的變化。這是因為這給父容器設(shè)置成了一個新的BFC寄雀,再結(jié)合之前的特性:BFC可以包含浮動 可知得滤,就是因為這個BFC的生成使得高度不塌陷。(使用其它屬性如display: table-cell也可使得高度不塌陷)

    父容器高度塌陷

后記

使用BFC并不是很好的解決方案盒犹,像一個外邊距合并問題給人帶來的困擾就非常大懂更,完全可以使用更簡單的方案 如給父元素添加透明的borderpadding來解決; 像是兩欄布局以及去除文字環(huán)繞效果急膀,也可以通過margin-left來解決膜蛔,使用overflow: hidden也會產(chǎn)生新的問題,如文字溢出無法顯示脖阵;最后一個更是可以使用清除浮動(添加.clearfix)來解決父元素高度塌陷。
這里使用BFC 僅僅是為了更好理解它而已 ~

參考文章:

深入理解BFC和Margin Collapse - w3cplus
BFC 神奇背后的原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末墅茉,一起剝皮案震驚了整個濱河市命黔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌就斤,老刑警劉巖悍募,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異洋机,居然都是意外死亡坠宴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門绷旗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喜鼓,“玉大人,你說我怎么就攤上這事衔肢∽” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵角骤,是天一觀的道長隅忿。 經(jīng)常有香客問我,道長邦尊,這世上最難降的妖魔是什么背桐? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蝉揍,結(jié)果婚禮上链峭,老公的妹妹穿的比我還像新娘。我一直安慰自己又沾,他們只是感情好熏版,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布纷责。 她就那樣靜靜地躺著,像睡著了一般撼短。 火紅的嫁衣襯著肌膚如雪再膳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天曲横,我揣著相機與錄音喂柒,去河邊找鬼。 笑死禾嫉,一個胖子當著我的面吹牛灾杰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熙参,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼艳吠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了孽椰?” 一聲冷哼從身側(cè)響起昭娩,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黍匾,沒想到半個月后栏渺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡锐涯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年磕诊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纹腌。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡霎终,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出升薯,到底是詐尸還是另有隱情神僵,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布覆劈,位于F島的核電站保礼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏责语。R本人自食惡果不足惜炮障,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坤候。 院中可真熱鬧胁赢,春花似錦、人聲如沸白筹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至系馆,卻和暖如春送漠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背由蘑。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工闽寡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尼酿。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓爷狈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親裳擎。 傳聞我的和親對象是個殘疾皇子涎永,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽?zāi)J的外補...
    _Yfling閱讀 13,748評論 1 92
  • 一、在什么場景下會出現(xiàn)外邊距合并各墨?如何合并指孤?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例 在CSS當中贬堵,相...
    dengpan閱讀 572評論 0 0
  • relative:生成相對定位的元素恃轩,通過top,bottom,left,right的位置相對于其正常位置進行定位...
    zx9426閱讀 940評論 0 2
  • 1.在什么場景下會出現(xiàn)外邊距合并蒸殿?如何合并筷厘?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例 概念:在CSS當...
    饑人谷_任磊閱讀 650評論 0 3
  • 在什么場景下會出現(xiàn)外邊距合并宏所?如何合并酥艳?如何不讓相鄰元素外邊距合并?給個父子外邊距合并的范例塊元素直接接觸的垂直外...
    老虎愛吃母雞閱讀 455評論 0 0