淺析BFC

原文連接: Fyerl's Blogcss

提及 BFC 其實有點像閉包在大多數人印象中的感受,平時都用過,但在不瞭解定義的狀況下大多數人卻又不知道這就是 BFC。之因此會想了解下什麼是 BFC,是由於前些日的一個簡單且常見的排版問題html

HTML 代碼結構以下css3

<div class="form-item">
  <span class="label">登陸名</span>
  <div class="content">
    <input type="text" placeholder="請輸入登陸名">
  </div>
</div>

label 的寬度是自適應的,content 需填充滿此行剩餘的區域。常規方法經過 flex 佈局,很簡單閉包

.form-item {
  display: flex;
}

.content {
  flex: 1;
}

可是 flex 的兼容性仍是不夠向下的,因而搜索了一下,獲得了這麼個方案app

.label {
  float: left;
}

.content {
  overflow: hidden;
}

label 給了個 float 能夠理解,但 content 寫了一個 overflow: hidden 是什麼意思?實則這裏的 content 就造成了一個 BFC,因此仍是先回到 BFC 這個概念上佈局

什麼是 BFC

BFC 即(Block Format Context)塊級格式化範圍,是 CSS2.1 中用於規定塊級盒子的渲染布局方式

如何觸發建立一個 BFC

  • root: 頁面的根元素
  • display: inline-block | flex | flow-root
  • position: absolute | fixed
  • overflow: hidden | auto | scroll

以上條件知足任一便會觸發建立一個 BFC,同時也能夠看出這些屬性的設置會產生一些額外的效果,好比僅僅是想觸發 BFC,卻使用了 overflow: scroll 致使元素出現了滾動條,因此具體使用哪一種方式觸發 BFC,仍是須要結合實際的業務場景flex

BFC 的特性以及使用場景

1、消除外邊距摺疊

<style>
  .block {
    background: #eee;
    overflow: hidden;
  }

  .item {
    height: 44px;
    margin: 12px 0;
    background: #666;
  }
</style>
<body>
  <div class="block"> 
    <p class="item"></p>
    <p class="item"></p>
  </div>
</body>

如上,兩個 item 均存在上、下 margin,理想狀況下,兩個 item 之間間距應是 24px,但結果只有 12px,這即是外邊距摺疊,兄弟元素外邊距不一樣時,取最大值。這種行爲只存在於兄弟元素在同一 BFC 下這種情形。若想消除外邊距摺疊,對上述代碼作一些改造,使兄弟元素存在於不一樣 BFC 之中便可spa

<style>
  .block {
    background: #eee;
    overflow: hidden;
  }

  .item-wrapper {
    overflow: hidden;
  }

  .item {
    height: 44px;
    margin: 12px 0;
    background: #666;
  }
</style>
<body>
  <div class="block">
    <div class="item-wrapper">
      <p class="item"></p>
    </div>
    <div class="item-wrapper">
      <p class="item"></p>
    </div>
  </div>
</body>

此時 item-wrapper 便造成了一個 BFC,解決了外邊距摺疊問題。相信你們遇到這種狀況習覺得常地會加一層外層元素再給個 overflow: hidden,但爲何 overflow: hidden 就能消除摺疊,其實背後是 BFC 的原理3d

2、清除浮動

<style>
  .block {
    padding: 12px;
    background: #eee;
  }

  .item {
    float: left;
    height: 44px;
    width: 100%;
    background: #666;
  }
</style>
<body>
  <div class="block">
    <p class="item"></p>
  </div>
</body>

此時內部 item 已脫離常規文檔流,父元素沒法被子元素撐起。若須要父元素包裹住子元素,一是經過常見的 clearfix 方案,二就是同過構造父元素爲 BFC,也就是經過你們熟悉的 overflow: hidden,這裏涉及到的特性就是 BFC 能包裹住本身的後代浮動元素code

<style>
  .block {
    padding: 12px;
    background: #eee;
    overflow: hidden;
  }

  .item {
    float: left;
    height: 44px;
    width: 100%;
    background: #666;
  }
</style>
<body>
  <div class="block">
    <p class="item"></p>
  </div>
</body>

3、防止被浮動元素覆蓋和圍繞浮動元素

<style>
  .block {
    padding: 12px;
    background: #eee;
    overflow: hidden;
  }

  .label {
    float: left;
    height: 44px;
    width: 200px;
    background: #999;
    margin-right: 12px;
  }
  
  .content {
    height: 68px;
    background: #666;
  }
</style>
<body>
  <div class="block">
    <p class="label"></p>
    <p class="content"></p>
  </div>
</body>

回到最開始的佈局問題上了,此時 label 浮動於 content 之上,若是 content 內填充了其餘元素,當 content 高度大於 label 必定高度時 content 內元素會被 label 覆蓋或文本元素會圍繞着 label。以下圖,固然不但願右側地址的第二行會從最左邊開始

此時一行代碼構造 content 爲 BFC,問題便解決了

<style>
  .block {
    padding: 12px;
    background: #eee;
    overflow: hidden;
  }

  .label {
    float: left;
    height: 44px;
    width: 200px;
    background: #999;
    margin-right: 12px;
  }
  
  .content {
    height: 68px;
    background: #666;
    overflow: hidden;
  }
</style>
<body>
  <div class="block">
    <p class="label"></p>
    <p class="content"></p>
  </div>
</body>

總結

本文對 BFC 稍做梳理,望對代碼中那些莫名的 overflow: hidden 的理解有所幫助。上文提到的 overflow: flow-root 能夠看下大漠的這篇文章《flow-root》

參考:

相關文章
相關標籤/搜索