你所不知道的BFC

真是一個小例子引發(fā)的“命案”呀谜悟,原本只是在想為什么一個容器內(nèi)的塊元素幾個塊元素會發(fā)生外邊距(margin collapse)商叹,然后找啊找啊找估蹄,就找到了BFC(Block Formating context)次绘。> 真是很福氣自己,被自己感動哭了

首先刽酱,我會從 BFC是什么喳逛? 如何形成BFC? BFC的應(yīng)用 這三個方面入手棵里。


1 BFC 是什么润文?

BFC 是web頁面中盒模型布局中的CSS渲染模式,定位機制屬于普通流模式殿怜。
一個塊格式化上下文(block formatting context) 是Web頁面的可視化CSS渲染出的一部分转唉。它是塊級盒布局出現(xiàn)的區(qū)域,也是浮動層元素進行交互的區(qū)域稳捆。

(我們都知道,CSS中的定位機制有三種形式:1 普通流模式 2 浮動 3 定位麦轰。)BFC其實就是一個獨立的布局環(huán)境乔夯,其中的元素不受外界影響。> 我知道你現(xiàn)在看到這里肯定還不知道我在說什么款侵,說實話末荐,我一開始看其他文章也是這樣的,還是繼續(xù)往下看新锈,回頭再來理解概念吧甲脏。

2 創(chuàng)建BFC

一個元素要創(chuàng)建BFC,需要滿足以下幾個條件妹笆,才能形成BFC块请。

  • float的值不是none.
  • position 的值不是static或者relative。
  • display的值是inline-block,table-cell,flex,table-caption或者inline-flex拳缠。(其實這個除了flex其他我好像都沒用過)
  • overflow的值不是visible含末。

所以辅甥,只要滿足以上四個條件就可以創(chuàng)建BFC了,但是,等等,我們要創(chuàng)建BFC干嘛梭姓?首先應(yīng)該知道BFC的實際用處,我們才會在實際應(yīng)用中使用它。那么接下來就是盔憨,BFC的作用,我會用好多個例子來證明一下讯沈。

3 BFC的特性 (人家雖然好用郁岩,也是有缺點的,例如外邊距合并問題)

  • 1 BFC內(nèi)的元素會導(dǎo)致 外邊距合并芙盘。 (在BFC當(dāng)中驯用,盒子都是從它的包含塊一個一個垂直放置的,兩個相鄰盒子的垂直間距取決于margin屬性儒老,所以兩個相鄰塊會發(fā)生垂直外邊距塌陷蝴乔。)
  • 2 BFC中每一個盒子的左外側(cè)緊貼包含塊的左側(cè),(從右到左的格式里驮樊,則為盒子右側(cè)緊貼包含快右側(cè))甚至有浮動也是如此薇正。(浮動的元素是脫離文檔流的,所以其他元素為將其當(dāng)作不存在)囚衔。
  • 3 計算BFC的高度時挖腰,浮動元素也會計算進內(nèi)。(所以练湿,你懂的猴仑,我們可以給包含有浮動元素的父元素,設(shè)置成BFC肥哎,就可以 解決浮動元素導(dǎo)致的父元素坍塌的問題辽俗。
  • 4 BFC元素不會與浮動元素重合。 !!!理解這個很重要!!!!

BFC元素不會與浮動元素重合篡诽。 我需要說明一點就是崖飘,這是一個清除浮動的很好的方式啊啊啊。
1 當(dāng)一個容器中有一個左浮動元素和一個BFC元素的時候杈女,BFC的寬度如果可以在剩余空間存放的話朱浴,就會顯示在浮動元素所在行的剩余空間內(nèi)。
2 當(dāng) BFC 的寬度大于容器剩余寬度時达椰,最新版本的瀏覽中只有firefox會在同一行顯示翰蠢,其它瀏覽器均換行。

是不是有點暈了啰劲,這個時候最好不要放棄躏筏,繼續(xù)往下看,重頭戲還在后頭呈枉,知道了這些基礎(chǔ)的東西之后趁尼,我們需要知道一些關(guān)于BFC的實踐應(yīng)用和基本原理埃碱。

4 BFC 實踐及其原理。

1 自適應(yīng)兩欄布局 (原理參照:BFC的第4條屬性酥泞。)

先看下面的代碼:

CSS部分:
   <style>
      .container {
          width:400px;
          margin:200px;
      }
      .leftpart {
          float: left;
          width:100px;
          height:200px;
          background: plum;
          color: white;
      }
      .rightpart {
          height:300px;
          background: pink;
          color: white;
      }
  </style>
html部分:
<body>
  <div class="container">
      <div class="leftpart">我是左邊的那一塊</div>
      <div class="rightpart">我是右邊的那一塊砚殿,聽說我會環(huán)繞在左邊的浮動元素上,我也是沒辦法啊芝囤,因為浮動元素是脫離文檔流的似炎,我誰將它當(dāng)作不存在,然后占據(jù)他所在的空間呢
      也只有將我設(shè)置成BFC的形式悯姊,我才不會這樣呢羡藐?不信你試一試</div>
  </div>
</body>

左邊的設(shè)置了左浮動,因為浮動元素脫離文檔流悯许,所以結(jié)果會是下面這個樣子仆嗦。

image.png

很顯然,這不是我們想要的結(jié)果先壕,前面提到了BFC的特性中瘩扼,有一條提到,BFC不會與浮動元素觸碰垃僚,那么我們是不是可以給右邊的元素設(shè)置成BFC集绰。
那么其實,就是在.rightpart設(shè)置多一個樣式屬性就可以了谆棺。

.rightpart {overflow:auto;}    // 前面提到了如何形成一個BFC栽燕,可以設(shè)置overflow不為visible。

那么改淑,我們來看看效果圖纫谅。

image.png

這樣,我們右邊的那一塊溅固,沒有設(shè)置寬度,會自動根據(jù)容易的寬度還有浮動元素的寬度兰珍,自適應(yīng)的分配寬度給右邊那一塊侍郭。這樣也給我們的自適應(yīng)布局提供了思路呀。
對了掠河,如果希望左右兩欄有間距亮元,你可以這么做。
你會發(fā)現(xiàn)唠摹,你給右邊那一塊設(shè)置了margin-left之后爆捞,并沒有你理想中那樣。假設(shè)我添加了

.rightpart {margin-left:20px;}  // 只是設(shè)置了20

你會發(fā)現(xiàn)勾拉。這兩欄看上去還是沒有間距的煮甥。其實從下圖可以發(fā)現(xiàn)盗温,不是margin不起作用。

image.png

我的理解是成肘,margin-left確實是起作用了卖局,但是它其實還是將浮動元素看做是不占據(jù)文檔流的,只是BFC元素的盒模型中border內(nèi)的不再去搶浮動元素的空間双霍,但是margin還是會搶占浮動元素的空間的砚偶。所以,要想看到兩欄有間距洒闸,需要設(shè)置的margin-left要大于leftpart的寬度染坯。
(當(dāng)然,這并不是明智之舉丘逸,要是你不知道leftpart的寬度单鹿,豈不是悲劇了)

試一下:

.rightpart {margin-left:120px;}  // 只是設(shè)置了120
image.png

其實,不用那么麻煩鸣个。我們只需要給 leftpart設(shè)置margin-right 就可以了羞反。
上面其實也只是想詳細的去理解這個過程。

.leftpart {margin-right:20px;}
image.png

不知道你有沒有發(fā)現(xiàn)囤萤,如果我們之前不設(shè)置BFC的話昼窗,也就是不給rightpart設(shè)置成BFC的話,直接就是設(shè)置rightpart的margin-left大于左浮動元素的寬度涛舍,也可以達到兩欄布局的效果澄惊,但是,~~~那樣很麻煩啊富雅,如果不知道寬度怎么辦掸驱。

所以,兩欄布局的最佳實踐應(yīng)該是: margin-left + BFC模式没佑。
(當(dāng)然毕贼,用flex布局會更加方便,但是這也不失為一種好方法呀蛤奢。)

2 解決含有浮動元素的父元素塌陷問題

首先鬼癣,這個問題的存在原因是因為浮動元素是脫離文檔流的,所以包裹浮動元素的父元素其實并不能被撐開啤贩,所以就會導(dǎo)致下面的結(jié)果待秃,看一下圖。

image.png

上例所示圖的代碼如下:

// 很明顯痹屹,兩個子模塊的定位都是浮動形式章郁,而父元素發(fā)生了坍塌。
html部分:
<body>
    <div class="mainPart">
        <div class="testpart"></div>
        <div class="testpart"></div>
    </div>
</body>

CSS部分:
       .mainPart {
            background: royalblue;
            border:1px solid olivedrab;
            width:500px;
        }
        .testpart {
            float: left;
            width:200px;
            height:200px;
            background: plum;
            margin:10px;
        }
那么志衍?怎么解決這個問題暖庄。

當(dāng)然聊替。你可以向通常的清除浮動的方法一樣,在父元素內(nèi)部添加一個空元素雄驹,設(shè)置clear:both;可以達到清除浮動的效果佃牛。

那如何通過設(shè)置一個BFC去清除浮動呢?

前面第3點中提到:
計算BFC的高度時医舆,浮動元素也會計算進內(nèi)俘侠。

所以,可以將父元素設(shè)置成BFC蔬将,就可以達到清除浮動爷速,清除高度坍塌問題。

// 給父元素添加以下樣式
   .mainPart {
          overflow:auto;
        }

那么霞怀,效果如下圖:

image.png

所以惫东,可以通過給父元素設(shè)置成BFC來清除浮動。

3 BFC內(nèi)部元素外邊距塌陷問題解決毙石。

前面提到的BFC的原理特性中廉沮,有一個就是外邊距合并問題。(這又是一個大boss,我最近也在看這方面的資料徐矩,后續(xù)會補上詳細的筆記的)

BFC垂直方向上的距離由margin值所決定滞时,同一個BFC內(nèi)的兩個相鄰元素的margin值會重疊。

什么意思捏~~~~
先看下圖:

image.png

其實兩個粉色的子元素滤灯,已經(jīng)設(shè)置了margin值為20了坪稽。按照道理來說的話,上下兩塊之間的距離應(yīng)該是40的鳞骤。但是這里只是20.也就是外邊距合并最后是取比較大的那一個窒百。
(其實我想了一下,我覺得這個外邊距合并用在這里挺好的呀豫尽,有時候如果我們想實現(xiàn)下面這樣一個效果篙梢,其實我覺得外邊距合并的存在反倒是好的呢)
只需要給每一個子元素設(shè)置margin為20即可。(當(dāng)然美旧,父元素和第一個子元素以及最后一個子元素也會發(fā)生合并問題渤滞, ~~啊啊啊,我后面會貼上一文章來解釋的陈症,~~)

image.png

針對這種子元素發(fā)生外邊距合并的處理方法。
我們可以將子元素重新設(shè)置成一個BFC就可以了震糖。
你想想录肯,一開始,在同一個BFC下的子元素之所以會發(fā)生垂直外邊距合并(對了吊说,外邊距合并只發(fā)生在垂直方向论咏,水平方向不會的优炬。),是因為父元素的高度是由子元素決定的厅贪,所以高度也會發(fā)生外邊距合并了蠢护。
解決方法就是,用一個元素給第二個子元素包在一個新的BFC內(nèi)养涮。

html部分:
<div class="father">
    <div class="son"></div>
    <div style="overflow: auto">    // 這里設(shè)置了父元素葵硕,同時設(shè)置overflow:auto。
        <div class="son" ></div>
    </div>
</div>
CSS部分:
  .father {
            width:100px;
            height:200px;
            background: red;
            /*margin:20px;*/
        }
        .son {
            width:30px;
            height:90px;
            margin: 20px;
            background: plum;
        }

這樣的話贯吓,結(jié)果就如下所示了:

image.png

后記: 我理解的BFC其實就是CSS中的一個渲染機制懈凹,BFC就相當(dāng)于一個盒子,內(nèi)部的元素與外界的元素互不干擾悄谐。它不會影響外部的布局介评,外部的布局也不會影響到它。你想一下爬舰,為什么設(shè)置了BFC之后就可以清除浮動们陆,我的理解就是,設(shè)置了BFC之后的元素就是一個獨立的個體情屹,內(nèi)部有浮動元素也不會再影響外部的元素了坪仇。那為什么設(shè)置了BFC之后,不會發(fā)生對周圍元素的環(huán)繞現(xiàn)象屁商,也是同一個道理烟很。所以,這么去想一想蜡镶,其實BFC我們就一直有在使用雾袱,只是自己不知道而已。

總算寫完了官还,有時候覺得自己理解和寫出來是完全兩碼事的東西芹橡,希望自己能夠繼續(xù)堅持吧。希望能夠幫助到你們望伦,也歡迎一起交流林说。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市屯伞,隨后出現(xiàn)的幾起案子腿箩,更是在濱河造成了極大的恐慌,老刑警劉巖劣摇,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珠移,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機钧惧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門暇韧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浓瞪,你說我怎么就攤上這事懈玻。” “怎么了乾颁?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵涂乌,是天一觀的道長。 經(jīng)常有香客問我钮孵,道長骂倘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任巴席,我火速辦了婚禮历涝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漾唉。我一直安慰自己荧库,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布赵刑。 她就那樣靜靜地躺著分衫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪般此。 梳的紋絲不亂的頭發(fā)上蚪战,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機與錄音铐懊,去河邊找鬼邀桑。 笑死,一個胖子當(dāng)著我的面吹牛科乎,可吹牛的內(nèi)容都是我干的壁畸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼茅茂,長吁一口氣:“原來是場噩夢啊……” “哼捏萍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起空闲,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤令杈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碴倾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逗噩,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡悔常,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了给赞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡矫户,死狀恐怖片迅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情皆辽,我是刑警寧澤柑蛇,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站驱闷,受9級特大地震影響耻台,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜空另,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一盆耽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扼菠,春花似錦摄杂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秧饮,卻和暖如春映挂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗尸。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工柑船, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人振劳。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓椎组,卻偏偏與公主長得像,于是被迫代替她去往敵國和親历恐。 傳聞我的和親對象是個殘疾皇子寸癌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

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

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J的外補...
    _Yfling閱讀 13,737評論 1 92
  • 一弱贼,浮動元素有什么特征蒸苇?對父容器、其他浮動元素吮旅、普通元素溪烤、文字分別有什么影響? 浮動模型是一種可視化格式模型味咳,浮動...
    DeeJay_Y閱讀 862評論 0 4
  • relative:生成相對定位的元素,通過top,bottom,left,right的位置相對于其正常位置進行定位...
    zx9426閱讀 932評論 0 2
  • 一掂铐、在什么場景下會出現(xiàn)外邊距合并?如何合并揍异?如何不讓相鄰元素外邊距合并全陨?給個父子外邊距合并的范例 在CSS當(dāng)中,相...
    dengpan閱讀 571評論 0 0
  • 1.在什么場景下會出現(xiàn)外邊距合并雨涛?如何合并?如何不讓相鄰元素外邊距合并懦胞?給個父子外邊距合并的范例 概念:在CSS當(dāng)...
    饑人谷_任磊閱讀 646評論 0 3