博客 / 詳情

返回

【CSS】有意思的BFC:Block Formatting Context(塊格式化上下文)!

前言

大家好,我是HoMeTown,今天想聊一聊CSS中的BFC,很多朋友應該都聽過這個名詞,搞懂BFC可以讓我們理解CSS中一些很詭異的地方,話不多説,直奔主題!

什麼是BFC

BFC是什麼?引用MDN的一段介紹:

塊格式化上下文(Block Formatting Context,BFC)  是 Web 頁面的可視 CSS 渲染的一部分,是塊級盒子的佈局過程發生的區域,也是浮動元素與其他元素交互的區域。

大白話講,我理解BFC其實就是CSS中的塊級作用域,包含上下文元素中的所有子元素,但不包括內創建了新的BFC的子元素的內部元素,也就是 A -> B -> C 但是 A !-> C,換句話講,一個元素不可能存在於兩個BFC中,因為如果一個元素存在於兩個不同的BFC,那麼這個元素就能和這兩個BFC中的子元素髮生作用,那就違法了BFC的初衷:隔離

BFC的渲染規則

BFC中有特定的渲染規則,如下:

  • 同一個BFC中兩個相鄰的元素的margin重疊問題
  • BFC在計算高度是,即使浮動的元素也會參與高度計算
  • BFC的區域不會與float的元素區域重疊
  • 每個元素的左外邊距與包含塊的左邊界相接觸,即使浮動也如此
  • 內部的盒子會一在垂直方向上一個個放置

BFC的觸發條件

  • 根元素(HTML標籤)
  • float
  • overflow != visible
  • display = inline-blocktable-celltable-captiontableinline-tableflexinline-flexgridinline-grid
  • postion = fixed / absolute

BFC的作用

防止相鄰元素的margin重疊

上面提到過,同一個BFC的兩個相鄰元素的上下margin會發生重疊,舉個🌰:

<style>
  p {
    width: 300px;
    height: 200px;
    margin: 100px;
    line-height: 200px;
    text-align: center;
    background-color: #f3eaff;
    color: #8857cd;
    font-weight: bold;
  }
</style>
  </head>
  <body>
    <p>HoMeTown</p>
    <p>你好朋友</p>
  </body>

頁面顯示如下:

aaa1.gif

同一個BFC中的兩個相鄰元素的margin上下重疊,此時我們需要手動創建新的BFC,解決這個問題,改動如下:

<style>
  p {
    width: 300px;
    height: 200px;
    margin: 100px;
    line-height: 200px;
    text-align: center;
    background-color: #f3eaff;
    color: #8857cd;
    font-weight: bold;
  }
  .wrapper {
    overflow: hidden;
  }
</style>
  </head>
  <body>
    <p>HoMeTown</p>
    <div class="wrapper">
      <p>你好朋友</p>
    </div>
  </body>

頁面展示如下:

aaa2.gif

margin恢復正常

BFC在計算高度是,即使浮動的元素也會參與高度計算

眾所周知,元素float脱離文檔流之後,會產生高度塌陷的問題,除了清除浮動,我們還可以通過BFC的特性去處理,舉個🌰:

<style>
  p {
    width: 300px;
    height: 200px;
    line-height: 200px;
    text-align: center;
    background-color: #f3eaff;
    color: #8857cd;
    font-weight: bold;
    float: left;
  }
  .wrapper {
    width: 600px;
    border: 4px solid #cfc;
  }
</style>
  </head>
  <body>
    <div class="wrapper">
      <p>HoMeTown</p>
      <p>你好朋友</p>
    </div>
  </body>

頁面展示如下:

image.png

因為子元素浮動的原因導致盒子.wrapper高度塌陷,此時我們手動創建BFC區域,再看看效果,改動如下:

.wrapper {
    width: 600px;
    border: 4px solid #cfc;
    overflow: hidden;
}

此時,頁面展示如下:

image.png

.wrapper的高度恢復正常!

每個元素的左外邊距與包含塊的左邊界相接觸

我們知道,如果盒子打開了float,脱離文檔流且不佔位,按照BFC的特點,塊內每個元素的左邊距都會與包含塊的左邊距重合,舉個🌰

   <style>
      body {
        position: relative;
      }
      .main {
        width: 300px;
        height: 200px;
        line-height: 200px;
        text-align: center;
        background-color: #f3eaff;
        color: #8857cd;
        font-weight: bold;
        border: 2px solid red;
      }
      .side {
        width: 100px;
        height: 200px;
        line-height: 200px;
        text-align: center;
        background-color: #f3eaff;
        color: #8857cd;
        font-weight: bold;
        border: 2px solid yellow;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="side">你好朋友</div>
    <div class="main">HoMeTown</div>
  </body>

頁面展示如下:

image.png

.side開啓浮動,左外邊距與body的左邊重合,.main也是,這並不是我們想看到的,那麼,可以利用BFC的特點,BFC包含上下文元素中的所有子元素,但不包括內創建了新的BFC的子元素的內部元素,手動給.main創建BFC,改動如下:

.main {
    ...
    overflow: hidden;
}

此時頁面展示如下:

image.png

成功!

總結

BFC內部的渲染規則,在現代flex佈局中其實有更多的解決方案,但是作為一個職業前端,還是需要了解一下。以上就是我的見解,不喜勿噴。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.