1. 程式人生 > >BFC概念及實用場景

BFC概念及實用場景

參考文章:

https://blog.csdn.net/m0_37585915/article/details/78501760

https://zhuanlan.zhihu.com/p/25321647

https://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html

BFC 概念

Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關係和相互作用。


那麼 BFC 是什麼呢?

BFC 即 Block Formatting Contexts (塊級格式化上下文),它屬於上述定位方案的普通流。

具有 BFC 特性的元素可以看作是隔離了的獨立容器,容器裡面的元素不會在佈局上影響到外面的元素,並且 BFC 具有普通容器所沒有的一些特性。

通俗一點來講,可以把 BFC 理解為一個封閉的大箱子,箱子內部的元素無論如何翻江倒海,都不會影響到外部。

三、觸發 BFC

只要元素滿足下面任一條件即可觸發 BFC 特性:

  • body 根元素
  • 浮動元素:float 除 none 以外的值
  • 絕對定位元素:position (absolute、fixed)
  • display 為  inline-block/ table-cell/ table-caption/ flex/ inline-flex 
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)

BFC原理–

  • BFC內部的盒子,會在垂直方向,一個接一個地放置。垂直方向上也會發生邊距重疊。
  • BFC就是頁面上的一個獨立容器,容器裡面的子元素不會影響到外面的元素,外邊的也不會影響裡邊的。
  • BFC的區域不會與float box重疊。
  • 計算BFC的高度時,浮動元素也被計算在內。

四、BFC 特性及應用

1. 同一個 BFC 下外邊距會發生摺疊


<head>
div{
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
}
</head>
<body>
    <div
></div> <div></div> </body>

從效果上看,因為兩個 div 元素都處於同一個 BFC 容器下 (這裡指 body 元素) 所以第一個 div 的下邊距和第二個 div 的上邊距發生了重疊,所以兩個盒子之間距離只有 100px,而不是 200px。

首先這不是 CSS 的 bug,我們可以理解為一種規範,如果想要避免外邊距的重疊,可以將其放在不同的 BFC 容器中。

<div class="container">
    <p></p>
</div>
<div class="container">
    <p></p>
</div>
.container {
    overflow: hidden;
}
p {
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
}

這時候,兩個盒子邊距就變成了 200px

2. BFC 可以包含浮動的元素(清除浮動)

我們都知道,浮動的元素會脫離普通文件流,來看下下面一個例子

<div style="border: 1px solid #000;">
    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>
由於容器內元素浮動,脫離了文件流,所以容器只剩下 2px 的邊距高度。如果使觸發容器的 BFC,那麼容器將會包裹著浮動元素。
<div style="border: 1px solid #000;overflow: hidden">
    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>

效果如圖:

3. BFC 可以阻止元素被浮動元素覆蓋

先來看一個文字環繞效果:

<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一個左浮動的元素</div>
<div style="width: 200px; height: 200px;background: #eee">我是一個沒有設定浮動, 
也沒有觸發 BFC 元素, width: 200px; height:200px; background: #eee;</div>

這時候其實第二個元素有部分被浮動元素所覆蓋,(但是文字資訊不會被浮動元素所覆蓋) 如果想避免元素被覆蓋,可觸第二個元素的 BFC 特性,在第二個元素中加入 overflow: hidden,就會變成:


這個方法可以用來實現兩列自適應佈局,效果不錯,這時候左邊的寬度固定,右邊的內容自適應寬度(去掉上面右邊內容的寬度)。

4.父元素中第一個子元素設定margin-top使margin-top提升至父元素的屬性。處理方式,讓父級成為BFC即可


說明:

margin摺疊的產生有幾個條件:

  • 這些margin都處於普通流中,並在同一個BFC中;
  • 這些margin沒有被非空內容、padding、border 或 clear 分隔開;
  • 這些margin在垂直方向上是毗鄰的,包括以下幾種情況:
    1、一個box的top margin與第一個子box的top margin
    2、一個box的bottom margin與最後一個子box的bottom margin,但須在該box的height 為auto的情況下
    3、一個box的bottom margin與緊接著的下一個box的top margin
    4、一個box的top margin與其自身的bottom margin,但須滿足沒建立BFC、零min-height、零或者“auto”的height、沒有普通流的子box

垂直方向上毗鄰的box不會發生摺疊的情況:

  • 根元素的外邊距不會參與摺疊
  • 一個有clearance的box的上下margin毗鄰,它會與緊接著的下一個box發生margin摺疊,但摺疊後的margin不會再與它們父box的bottom margin摺疊

摺疊邊距的計算

當兩個margin都是正值的時候,取兩者的最大值;當 margin 都是負值的時候,取的是其中絕對值較大的,然後,從 0 位置,負向位移;當有正有負的時候,先取出負 margin 中絕對值中最大的,然後,和正 margin 值中最大的 margin 相加。但必須注意,所有毗鄰的margin要一起參與運算,不能分步進行。

合併原則:

合併外邊距與BFC

在CSS當中,相鄰的兩個盒子(可能是兄弟關係也可能是祖先關係)的外邊距可以結合成一個單獨的外邊距。這種合併外邊距的方式被稱為摺疊,並且因而所結合成的外邊距稱為摺疊外邊距。

著作權歸作者所有。
商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: https://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html © w3cplus.com

摺疊的結果:

  1. 兩個相鄰的外邊距都是正數時,摺疊結果是它們兩者之間較大的值。
  2. 兩個相鄰的外邊距都是負數時,摺疊結果是兩者絕對值的較大值。
  3. 兩個外邊距一正一負時,摺疊結果是兩者的相加的和。

產生摺疊的必備條件:margin必須是鄰接的!

而根據w3c規範,兩個margin是鄰接的必須滿足以下條件:

  • 必須是處於常規文件流(非float和絕對定位)的塊級盒子,並且處於同一個BFC當中。
  • 沒有線盒,沒有空隙(clearance,下面會講到),沒有padding和border將他們分隔開
  • 都屬於垂直方向上相鄰的外邊距,可以是下面任意一種情況
    • 元素的margin-top與其第一個常規文件流的子元素的margin-top
    • 元素的margin-bottom與其下一個常規文件流的兄弟元素的margin-top
    • height為auto的元素的margin-bottom與其最後一個常規文件流的子元素的margin-bottom
    • 高度為0並且最小高度也為0,不包含常規文件流的子元素,並且自身沒有建立新的BFC的元素的margin-top和margin-bottom
著作權歸作者所有。
商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
原文: https://www.w3cplus.com/css/understanding-bfc-and-margin-collapse.html © w3cplus.com