BFC是啥?(清除浮動(dòng)與外邊距合并問(wèn)題)

BFC是什么?

入門FE了那么久,BFC這個(gè)名詞倒是第一次知道,特地前去了解了一下,幡然醒悟,這不就是平常我們寫block和inline的標(biāo)準(zhǔn)文檔流嗎?(恕我不專業(yè)的描述方式),估計(jì)是自己知識(shí)面太窄了,不然咋會(huì)在學(xué)習(xí)CSS的時(shí)候錯(cuò)過(guò)捏,呵呵噠。

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
————W3C

中文直譯為塊級(jí)格式上下文(或塊級(jí)上下文)。其實(shí)就是我們平常的塊級(jí)元素自頂向下排列,同級(jí)之間的containing block頂部一個(gè)接一個(gè)垂直排列,水平方向上撐滿寬度。
因?yàn)閮蓚€(gè)相鄰的BFC之間距離由margin決定,在同一個(gè)BFC內(nèi)部,兩個(gè)垂直方向相鄰的塊級(jí)元素margin值會(huì)"共用",導(dǎo)致塌陷。也是經(jīng)典的外邊距塌陷問(wèn)題。

以下方法可以創(chuàng)建一個(gè)新的塊級(jí)執(zhí)行上下文(BFC):
  • 浮動(dòng)元素
  • 絕對(duì)定位元素
  • 塊級(jí)元素以及塊級(jí)容器(比如inline-block、table-cell、table-capation)
  • overflow值不為visible的塊級(jí)盒子
    當(dāng)然,root元素會(huì)自動(dòng)生成一個(gè)BFC,這個(gè)應(yīng)該很好理解,畢竟需要一個(gè)根BFC來(lái)布局
執(zhí)行規(guī)則:
  1. 在一個(gè)塊級(jí)排版上下文中,盒子是從包含塊頂部開(kāi)始,垂直的一個(gè)接一個(gè)的排列的。每個(gè)盒子的左外邊是觸碰到包含塊的左邊的(對(duì)于從右向左的排版,則相反)
  2. 相鄰兩個(gè)盒子之間的垂直的間距是被margin屬性所決定的,在一個(gè)塊級(jí)排版上下文中相鄰的兩個(gè)塊級(jí)盒之間的垂直margin是折疊的。

注意:這里著重了解一下,什么是同一個(gè)BFC、根BFC,有何區(qū)別


我們來(lái)實(shí)現(xiàn)它。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            div {
                width: 200px;
                height: 100px;
            }
            .a {
                background-color: red;
            }
            .b {
                background-color: orange;
            }
            .c {
                background-color: deepskyblue;
            }
            .d {
                background-color: black;
                margin: 20px;
            }
            .e {
                background-color: green;
                margin: 20px;
            }
        </style>
    </head>
    <body>
        <div class="a"></div>
        <div class="b"></div>
        <div class="c"></div>
        <div class="d"></div>
        <div class="e"></div>
    </body>
</html>
示例1
實(shí)例一

這是最普通的塊級(jí)排版上下文,現(xiàn)在問(wèn)題來(lái)了,這里有新的BFC嗎?對(duì)比那4個(gè)方法......沒(méi)有對(duì)嗎,所以,這里的所有class都是同一種BFC或者說(shuō)同一個(gè)BFC(這個(gè)準(zhǔn)確些吧),他們遵守執(zhí)行規(guī)則第一項(xiàng),依次向下排列......
.d.e我加了margin值,但是我們發(fā)現(xiàn),兩者中間的垂直margin并沒(méi)有生效,否則應(yīng)該是40px才對(duì)。
這就是執(zhí)行規(guī)則2生效了。

  1. 垂直margin合并
    在CSS當(dāng)中,相鄰的兩個(gè)盒子的外邊距可以結(jié)合成一個(gè)單獨(dú)的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結(jié)合成的外邊距稱為折疊外邊距。
    折疊的結(jié)果:
  • 兩個(gè)相鄰的外邊距都是正數(shù)時(shí),折疊結(jié)果是它們兩者之間較大的值。
  • 兩個(gè)相鄰的外邊距都是負(fù)數(shù)時(shí),折疊結(jié)果是兩者絕對(duì)值的較大值。
  • 兩個(gè)外邊距一正一負(fù)時(shí),折疊結(jié)果是兩者的相加的和。
  • 這個(gè)同樣可以利用BFC解決。關(guān)于原理在前文已經(jīng)講過(guò)了。
    ————引用自簡(jiǎn)書蘇星河

所以我們用BFC解決margin合并,如何解決呢?就是建立一個(gè)新的BFC,使得他倆沒(méi)有關(guān)系。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            div {
                width: 200px;
                height: 100px;
            }
            .d {
                background-color: black;
                margin: 20px;
                display: inline-block;
            }
            .e {
                background-color: green;
                margin: 20px;
            }
        </style>
    </head>
    <body>
        <div class="d"></div>
        <div class="e"></div>
    </body>
</html>
示例二
示例二

在其中一個(gè)div的display改為inline-block,創(chuàng)建一個(gè)新的BFC,使得兩者BFC所屬不同。


浮動(dòng)父容器塌陷問(wèn)題
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .wrap {
                border: solid 1px red;
                width: 250px;
            }
            .a,.b {
                width: 100px;
                height: 50px;
                background-color: orange;
                float: left;
            }
            .b {
                background-color: blue;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="a"></div>
            <div class="b"></div>
        </div>
    </body>
</html>
示例三

我是這么理解的,內(nèi)部的兩個(gè)div由于float,所以不在屬于root BFC,則外容器內(nèi)部不再有同樣的BFC,判定為無(wú)內(nèi)容(這里其實(shí)有歧義),所以紅色框沒(méi)有撐開(kāi)。

從BFC的角度看解決方法


我們調(diào)整一下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .wrap {
                border: solid 5px red;
                width: 250px;
                overflow: hidden;
            }
            .a,.b {
                width: 100px;
                height: 50px;
                background-color: orange;
                float: left;
            }
            .b {
                background-color: blue;
            }
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="a"></div>
            <div class="b"></div>
        </div>
    </body>
</html>
示例三
通過(guò)對(duì)父容器添加overflow:hidden,改變它的BFC,這樣處于同樣的BFC下的容器就會(huì)將子div內(nèi)容算入,撐開(kāi)父容器。

BFC與文字環(huán)繞
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .ct {
                border: solid 1px black;
            }
            .aside {
                width: 50px;
                height: 50px;
                background-color: red;
                float: left;
            }
            .content {
                background-color: orange;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="aside"></div>
            <div class="content">公園里還有一處燒烤區(qū),一邊看著遠(yuǎn)處聳立的高樓,一邊吃著燒烤,也許臉書的員工就是喜歡這種自然田園的風(fēng)光。
說(shuō)實(shí)話,在硅谷這個(gè)寸土寸金的地方,臉書總部里能有這么大一塊地作為公園我覺(jué)得是挺奢侈的,但是真的要比較起來(lái),國(guó)內(nèi)很多公園都比這個(gè)要做地精致和好看。連作者本人也這么覺(jué)得:</div>
        </div>
    </body>
</html>
文字盒子被擠壓,文字少
文字增多

如何做到和右圖一樣呢?
先看看造成這個(gè)現(xiàn)象的原因

橙色區(qū)域?yàn)?code>line-boxs,從表面看,文字盒子被浮動(dòng)紅盒子擠壓到了左邊,實(shí)際上,由于紅盒子浮動(dòng),是新的BFC,文字盒子實(shí)際上是從父容器左邊開(kāi)始的,文字盒子實(shí)際上處于浮動(dòng)元素的下方。文字盒子進(jìn)行了移位,水平收縮為浮動(dòng)元素提供了空間。
隨著文字增加,文字盒子最終將會(huì)環(huán)繞在浮動(dòng)元素下方,也就是現(xiàn)在這樣。

我們?nèi)绻芤苿?dòng)文字盒子,也就是文字的容器,就可以使它不環(huán)繞了。此處想一想W3C的概念:

In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itselfmay become narrowerdue to the floats).
在BFC中,每個(gè)盒子的左外邊框緊挨著左邊框的包含塊(從右到左的格式化時(shí),則為右邊框緊挨)。即使在浮動(dòng)里也是這樣的(盡管一個(gè)盒子的邊框會(huì)因?yàn)楦?dòng)而萎縮),除非這個(gè)盒子的內(nèi)部創(chuàng)建了一個(gè)新的BFC(這種情況下,由于浮動(dòng),盒子本身將會(huì)變得更窄),

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .ct {
                border: solid 1px black;
            }
            .aside {
                width: 50px;
                height: 50px;
                background-color: red;
                float: left;
            }
            .content {
                background-color: orange;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
        <div class="ct">
            <div class="aside"></div>
            <div class="content">公園里還有一處燒烤區(qū),一邊看著遠(yuǎn)處聳立的高樓,一邊吃著燒烤,也許臉書的員工就是喜歡這種自然田園的風(fēng)光。
說(shuō)實(shí)話,在硅谷這個(gè)寸土寸金的地方,臉書總部里能有這么大一塊地作為公園我覺(jué)得是挺奢侈的,但是真的要比較起來(lái),國(guó)內(nèi)很多公園都比這個(gè)要做地精致和好看。連作者本人也這么覺(jué)得:</div>
        </div>
    </body>
</html>

文字盒子添加overflow:hidden,使得處于新的BFC中,就不會(huì)根據(jù)上面的W3C概念規(guī)則來(lái)繪制了。


MDN——外邊距合并
蘇星河:【CSS】深入理解BFC原理及應(yīng)用
CSS深入理解流體特性和BFC特性下多欄自適應(yīng)布局
CSS布局基礎(chǔ):BFC
理解CSS中BFC
BFC神器背后的原理


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,115評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 177,577評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,514評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,234評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,621評(píng)論 1 326
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,822評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,380評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,128評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,319評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,548評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,970評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,229評(píng)論 1 291
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,048評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,285評(píng)論 2 376

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

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,779評(píng)論 1 92
  • relative:生成相對(duì)定位的元素,通過(guò)top,bottom,left,right的位置相對(duì)于其正常位置進(jìn)行定位...
    zx9426閱讀 957評(píng)論 0 2
  • 1.浮動(dòng)元素有什么特征?對(duì)父容器、其他浮動(dòng)元素、普通元素、文字分別有什么影響? 浮動(dòng)元素不在文檔的普通流中,它可以...
    饑人谷_Young丶K閱讀 459評(píng)論 0 0
  • 一,浮動(dòng)元素有什么特征?對(duì)父容器、其他浮動(dòng)元素、普通元素、文字分別有什么影響? 浮動(dòng)模型是一種可視化格式模型,浮動(dòng)...
    DeeJay_Y閱讀 893評(píng)論 0 4
  • 1.在什么場(chǎng)景下會(huì)出現(xiàn)外邊距合并?如何合并?如何不讓相鄰元素外邊距合并?給個(gè)父子外邊距合并的范例 概念:在CSS當(dāng)...
    饑人谷_任磊閱讀 668評(píng)論 0 3