【轉】[佈局概念] 關於CSS-BFC深入理解
原文:https://juejin.cn/post/6844903476774830094
寫在前面
好記性不如爛筆頭,研究了一下BFC,發現裡面比較細的東西也是很多的!關於BFC,很多人可能都聽說過BFC這個東西,大概知道這是個啥東西,相信很多人對此並沒有一個非常細緻的瞭解,本文預計篇幅較長,認真,耐著性子看,應該都能夠比較深入的理解BFC這個概念的規則、作用以及用法。希望喜歡的朋友可以點個贊,或者關注一波本人,謝謝。
BFC是什麼鬼?
BFC概括:可以在心中記住這麼一個概念———所謂的BFC就是css佈局的一個概念,是一塊區域,一個環境。
先穩住別懵逼,接著往下走。
關於BFC的定義:
BFC(Block formatting context)直譯為"塊級格式化上下文"。它是一個獨立的渲染區域
我們常說的文件流其實分為定位流、浮動流和普通流三種。而普通流其實就是指BFC中的FC。
FC是formatting context的首字母縮寫,直譯過來是格式化上下文,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其他元素之間的關係和作用。
常見的FC有BFC、IFC(行級格式化上下文),還有GFC(網格佈局格式化上下文)和FFC(自適應格式化上下文),這裡就不再展開了。
通俗一點的方式解釋:
BFC 可以簡單的理解為某個元素的一個 CSS 屬性
下面列一波目錄,然後分別展開來講:
觸發條件或者說哪些元素會生成BFC:
滿足下列條件之一就可觸發BFC
【1】根元素,即HTML元素
【2】float的值不為none
【3】overflow的值不為visible
【4】display的值為inline-block、table-cell、table-caption
【5】position的值為absolute或fixed
BFC佈局規則:
1.內部的Box會在垂直方向,一個接一個地放置。
2.Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
3.每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
4.BFC的區域不會與float box重疊。
5.BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
6.計算BFC的高度時,浮動元素也參與計算
BFC有哪些作用:
- 自適應兩欄佈局
2可以阻止元素被浮動元素覆蓋
3可以包含浮動元素——清除內部浮動
4.分屬於不同的BFC時可以阻止margin重疊
BFC佈局規則1:內部的Box會在垂直方向,一個接一個地放置。
上文定義中提到過的塊級盒:block-level box,在這裡解析一波:
這個就是我們平常操作盒子的組成
我們平常說的盒子是由margin、border、padding、content組成的,實際上每種型別的四條邊定義了一個盒子,分別是分別是content box、padding box、border box、margin box,這四種類型的盒子一直存在,即使他們的值為0.決定塊盒在包含塊中與相鄰塊盒的垂直間距的便是margin-box。
提示:Box之間的距離雖然也可以使用padding來控制,但是此時實際上還是屬於box內部裡面,而且使用padding來控制的話就不能再使用border屬性了。
佈局規則1就是我們平常div一行一行塊級放置的樣式,大家想一下就知道了,這裡就不展開了。
BFC佈局規則2:Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊。
上文提到過,決定塊盒在包含塊中與相鄰塊盒的垂直間距的便是margin-box。,上面的栗子就是這種情況。
演示中css屬性設定:上面的box:margin-bottom: 100px;下面的box:margin-top: 100px;(他們是同一側的margin,所以會發生margin重疊的情況,兩個div的距離實際上只有100px。)
BFC的作用4:阻止margin重疊:
當兩個相鄰塊級子元素分屬於不同的BFC時可以阻止margin重疊
操作方法:給其中一個div外面包一個div,然後通過觸發外面這個div的BFC,就可以阻止這兩個div的margin重疊
下面是程式碼:
<div class="aside"></div>
<div class="text">
<div class="main"></div>
</div>
<!--下面是css程式碼-->
.aside {
margin-bottom: 100px;//margin屬性
width: 100px;
height: 150px;
background: #f66;
}
.main {
margin-top: 100px;//margin屬性
height: 200px;
background: #fcc;
}
.text{
/*盒子main的外面包一個div,通過改變此div的屬性使兩個盒子分屬於兩個不同的BFC,以此來阻止margin重疊*/
overflow: hidden;//此時已經觸發了BFC屬性。
}複製程式碼
ps:觸發方式可以參考上文給出的觸發條件。
這裡有一個網址可以線上演示,通過演示,可以更直觀一點:
這裡面也是一篇好文章,關於BFC的
連結地址:www.cnblogs.com/xiaohuochai…
BFC佈局規則3:每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
<div class="par">
<div class="child"></div>
//給這兩個子div加浮動,浮動的結果,如果沒有清除浮動的話,父div不會將下面兩個div包裹,但還是在父div的範圍之內。
<div class="child"></div>
</div>複製程式碼
解析:給這兩個子div加浮動,浮動的結果,如果沒有清除浮動的話,父div不會將下面兩個div包裹,但還是在父div的範圍之內,左浮是子div的左邊接觸父div的borderbox的左邊,右浮是子div接觸父div的borderbox右邊,除非設定margin來撐開距離,否則一直是這個規則。
BFC作用3:可以包含浮動元素——清除內部浮動
給父divpar加上 overflow: hidden;
清除浮動原理:觸發父div的BFC屬性,使下面的子div都處在父div的同一個BFC區域之內,此時已成功清除浮動。
還可以向同一個方向浮動來達到清除浮動的目的,清除浮動的原理是兩個div都位於同一個浮動的BFC區域之中。
BFC佈局規則4:BFC的區域不會與float box重疊:
<div class="aside"></div>
<div class="text">
<div class="main"></div>
</div>
<!--下面是css程式碼-->
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
overflow: hidden;//觸發main盒子的BFC
background: #fcc;
}
.text{
width: 500px;
}複製程式碼
上面aside盒子有一個浮動屬性,覆蓋了main盒子的內容,main盒子沒有清除aside盒子的浮動。只做了一個動作,就是觸發自身的BFC,然後就不再被aside盒子覆蓋了。所以:BFC的區域不會與float box重疊。
BFC作用:自適應兩欄佈局。
還是上面的程式碼,此時BFC的區域不會與float box重疊,因此會根據包含塊(父div)的寬度,和aside的寬度,自適應寬度。
BFC 與 Layout
IE 作為瀏覽器中的奇葩,當然不可能按部就班的支援 BFC 標準,於是乎 IE 中有了 Layout 這個東西。Layout 和 BFC 基本是等價的,為了處理 IE 的相容性,在需要觸發 BFC 時,我們除了需要用觸發條件中的 CSS 屬性來觸發 BFC,還需要針對 IE 瀏覽器使用 zoom: 1 來觸發 IE 瀏覽器的 Layout。
有趣的文字:
.par {
margin-top: 3rem;
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}複製程式碼
當我使用上面的屬性,再加上一個沒有屬性的p或者span標籤,就發現兩個子div的float屬性自動被清除了,這是因為span或者p這類文字自帶一個BFC嗎?還是什麼?求路過的大神解釋。。。
以上是錯誤的。這裡兩個div被撐開,是因為父div被p標籤撐開了,並不是因為清除浮動的原因,從下面這張圖片可以清楚的知道。
其實以上的幾個例子都體現了BFC佈局規則第五條————
BFC佈局規則5:BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
文字環繞float:
<div style="float: left; width: 100px; height: 100px; background: #000;">
</div>
<div style="height: 200px; background: #AAA;">
<div style=" width: 30px; height: 30px; background: red;"></div>
<p>content</p> <p>content</p> <p>content</p> <p>content</p> <p>content</p>
</div>複製程式碼
問題:為什麼 div 的左上角被覆蓋了,而文字卻沒有被覆蓋,float不是應該跟普通流不在一個層級嗎?是因為float屬性不生效嗎?
解決:
float的定義和用法:
float 屬性定義元素在哪個方向浮動。以往這個屬性總應用於影象,使文字圍繞在影象周圍,不過在 CSS 中,任何元素都可以浮動。浮動元素會生成一個塊級框,而不論它本身是何種元素。
從上圖可以看到,float屬性確實生效,將float隱藏後,下面還有一個紅色的div,這個div是被黑色div所覆蓋掉的。div會被float覆蓋,而文字卻沒有被float覆蓋,是因為float當初設計的時候就是為了使文字圍繞在浮動物件的周圍。
後話
上面說的有些東西,其實在我們平常的佈局中,已經有在使用這些規律,只是沒有總結出來,如果寫的不好之處歡迎批評指導。還有一篇關於閉包的,還沒寫完。。五一三天淨打遊戲了!應該很快就會寫好了。
最後:碼字不易,感謝支援!因為我經常看不懂別人寫的分享,所以個人寫文比較偏小白,寫的不好之處,歡迎指點。然後就是希望看完的朋友點個喜歡,也可以關注一下我。
ps:目前待業,座標北京,本人適應網際網路快節奏,高強度,持續學習,持續成長,認真,嚴謹,學習積極性強。中小公司大佬求帶走,郵箱:[email protected]。
掘金個人主頁 ,簡書主頁連結,csdn部落格主頁連結
參考連結:
BFC神奇背後的原理,
深入理解BFC
什麼是BFC
Block Formatting Context (BFC) 淺析
以上。2017.5.4.