博客 / 詳情

返回

[CSS篇]淺談BFC

概述

説到BFC,其實剛開始我也很迷,翻看了一些文檔後打算來 總結一下,首先,BFC其實就是一種佈局,説到CSS佈局,大抵也就是普通流、浮動(元素會脱離普通流)、定位(元素會脱離普通流),BFC也屬於普通流,加了BFC樣式的元素像是給元素加了個結界,結界內部的元素不會影響外面的元素,被隔離開了。

BFC規則

• BFC就是一個塊級元素,塊級元素會在垂直方向一個接一個的排列;
• BFC樣式的元素像是給元素加了個結界,結界內部的元素不會影響外面的元素,被隔離開了;
• 垂直方向的距離由margin決定, 屬於同一個BFC的兩個相鄰的標籤外邊距會發生重疊;
• 計算BFC的高度時,浮動元素也參與計算;
• BFC佈局是可以通過一些條件觸發的,從而實現佈局上的需求或解決一些問題;
• BFC就是一個工具,知道其是什麼且怎麼用就好;
• BFC可以看做是一個CSS元素屬性

BFC觸發條件

• 根元素(<html>)
• float值非none,即left,right)
• overflow值非visible即hidden,auto,scroll
• display值為inline-block、table-cell、table-caption、table、table-row、table-row-group、table-header-group、table-footer-group、inline-table、flow-root、flex、inline-grid、inline-flex。
• position值為absolute、fixed

注意 :
1、並不是所有元素都是BFC,只有滿足了BFC的條件後,此元素才成為了1個BFC。
2、一個BFC區域,只包含其所有子元素,不包含子元素的子元素,舉個例子,爺爺只養兒子不養孫子,孫子是兒子負責。

舉個例子:

<body>
    <div class="test1"></div>
    <div class="test2"></div>
    <div class="test2">
      <h1>hello</h1>
      <h1>world!</h1>
    </div>
  </body>

上述代碼,body元素算1個BFC,其子元素為test1,test2,但不包括test2裏的兩個h1標籤,此時test2也不是BFC,因為不滿足任何BFC條件。
要想test2成為一個BFC,給其設置為上述的任何一個條件即可

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .test2 {
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="test1"></div>
    <div class="test2"></div>
    <div class="test2">
      <h1>hello</h1>
      <h1>world!</h1>
    </div>
  </body>
</html>

BFC的應用場景

1、屬於同一個BFC的兩個相鄰容器的上下margin會重疊

<html>
  <head>
    <style type="text/css">
      .top {
        width: 200px;
        height: 200px;
        background: red;
        margin-bottom: 40px;
      }
      .bottom {
        width: 200px;
        height: 200px;
        background: green;
        margin-top: 60px;
      }
    </style>
  </head>
  <body>
    <div class="top"></div>
    <div class="bottom"></div>
  </body>
</html>

效果圖:
image.png
如圖所示綠色盒子的上邊距是60px,紅色盒子的下邊距是40px,會選取最大的60px。這種現象叫做margin塌陷。
原因:因為此時紅盒子和綠盒子屬於同一個BFC,也就是根元素(<html>),BFC的特性1規定“屬於同一個BFC的兩個相鄰容器的上下margin會重疊,故兩者上下邊距發生重疊”

解決方案:
分離兩個盒子,使它們處於不同的BFC就互不干涉了,給綠盒子加個div,其式樣為overflow:hidden,分離BFC後就可以解決 margin重疊的問題了。

<html>
  <head>
    <style type="text/css">
      .top {
        width: 200px;
        height: 200px;
        background: red;
        margin-bottom: 40px;
      }
      .bottom {
        width: 200px;
        height: 200px;
        background: green;
        margin-top: 60px;
      }
      .box {
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div class="top"></div>
    <div class="box">
      <div class="bottom"></div>
    </div>
  </body>
</html>

image.png
image.png
2、計算BFC高度時浮動元素也參與計算

<html>
  <head>
    <style type="text/css">
      .outside {
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        /* float: left; */
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

我們先看下正常情況,有兩個盒子(div)=》outside為父元素,inside為子元素。父元素的樣式設置了邊框,目的想包裹住子元素。
效果圖:
image.png
下面我們把子元素設置浮動,脱離文檔流。float:left;

<html>
  <head>
    <style type="text/css">
      .outside {
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

效果圖:
image.png
子元素設置了浮動,脱離了文檔流,所以造成上圖現象。
原因:父元素沒有設置高度且子元素設置浮動的時候,父元素就會出現高度塌陷。
來我們看下給父元素設置高度是什麼效果。

<html>
  <head>
    <style type="text/css">
      .outside {
        height: 200px;
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

image.png

解決方案:
要麼給父元素添加高度,要麼給父元素樣式添加overflow:hidden

<html>
  <head>
    <style type="text/css">
      .outside {
        overflow: hidden;
        border: 10px solid blue;
      }
      .inside {
        width: 200px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
    </style>
  </head>
  <body>
    <div class="outside">
      <div class="inside"></div>
    </div>
  </body>
</html>

image.png
原因:給父元素添加樣式overflow:hidden。父元素觸發了BFC,BFC特性規定計算BFC高度時浮動元素也參與計算,這裏子元素設置了浮動,因為BFC所以其高度仍計算到父元素內,從而解決了高度塌陷的問題。

3、BFC的區域不會與浮動容器發生重疊
兩個相關的盒子,盒子1設置了左浮動,脱離了文檔流,所以不會自適應兩欄。兩個盒子發生了重疊。

<html>
  <head>
    <style type="text/css">
      .left {
        width: 100px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
      .right {
       width: 300px;
       height: 300px;
        background: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

效果圖:
image.png
解決方案:
給右側元素設置樣式overflow:hidden,使得右側元素觸發BFC,BFC特性規定:BFC的區域不會與浮動容器發生重疊,觸發BFC解決重疊問題,實現自適應兩欄效果。

<html>
  <head>
    <style type="text/css">
      .left {
        width: 100px;
        height: 200px;
        background: yellowgreen;
        float: left;
      }
      .right {
        width: 300px;
        height: 300px;
        overflow: hidden;
        background: blue;
      }
    </style>
  </head>
  <body>
    <div class="left"></div>
    <div class="right"></div>
  </body>
</html>

效果圖:
image.png

4、BFC內的容器在垂直方向依次排列
類似正常情況下塊元素在垂直方向上依次排列,較易理解。
5、BFC是獨立容器,容器內部元素不會影響容器外部元素
(解決包含塌陷)

<head>
    <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: blueviolet;
      }
      .son {
        width: 100px;
        height: 100px;
        background: burlywood;
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>

效果圖:
image.png
原因:
父元素也跟着子元素的margin-top下移了50px;
解決方案:
設置父元素為一個BFC區域

 <head>
    <style>
      .father {
        width: 300px;
        height: 300px;
        background-color: blueviolet;
        overflow: hidden;
      }
      .son {
        width: 100px;
        height: 100px;
        background: burlywood;
        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div class="father">
      <div class="son"></div>
    </div>
  </body>

效果圖:
image.png
7、使用BFC實現左側盒子定寬,右側盒子自適應佈局
左側設置為浮動,右側也設置為浮動,右側的寬度計算為100%-左側

<style>
     .left {
       width: 300px;
       height: 600px;
       background-color: aqua;
       float: left;
     }
     .right {
       /* width: calc(100% - 300px); */
       float: left;
       height: 600px;
       background-color: blueviolet;
     }
   </style>
 </head>
 <body>
   <div class="left"></div>
   <div class="right"></div>
 </body>

不加BFC的效果圖:
image.png
加了BFC的效果圖:
image.png

補充知識點:

使用display屬性能夠將三者任意轉換:
   (1)display:inline;轉換為行內元素
   (2)display:block;轉換為塊狀元素
   (3)display:inline-block;轉換為行內塊狀元素

① 行內元素:

(1)設置寬高無效
(2)對margin僅設置左右方向有效,上下無效;padding設置上下左右都有效,即會撐大空間
(3)不會自動進行換行

② 塊狀元素:

(1)能夠識別寬高
(2)margin和padding的上下左右均對其有效
(3)可以自動換行
(4)多個塊狀元素標籤寫在一起,默認排列方式為從上至下

③行內塊狀元素特徵:

(1)不自動換行
(2)能夠識別寬高
(3)默認排列方式為從左到右

使用display屬性能夠將三者任意轉換:

(1)display:inline;轉換為行內元素
(2)display:block;轉換為塊狀元素
(3)display:inline-block;轉換為行內塊狀元素

參考文章:https://www.itcast.cn/news/20...
https://blog.csdn.net/leelxp/...

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

發佈 評論

Some HTML is okay.