1. 程式人生 > >CSS中的BFC解析

CSS中的BFC解析

CSS的BFC

 BFC 即塊級格式上下文(Block Formatting Context),它是指一個獨立的塊級渲染區域,只有block-level的box參與,該區域擁有一套渲染規則來約束塊級盒子的佈局,且與區域外部無關。

BFC的生成

 CSS2.1規定滿足一下條件之一就會生成BFC:

  1. 根元素
  2. float的值不為none
  3. overflow的值不為visible
  4. position的值為fixed或absolute
  5. display的值為table-cell / table-caption / inline-block / flex / inline-flex

BFC的佈局規則

 上面說了,生成BFC的區域會有一套渲染規則來約束塊級盒子內的佈局;這些約束規則如下:

  1. 內部的塊級元素會在垂直方向,一個接一個地放置
  2. 每個元素的左外邊距與包含塊的左邊界相接觸(從左向右),即使浮動元素也是如此。(這說明BFC中子元素不會超出他的包含塊,而position為absolute的元素可以超出他的包含塊邊界)
  3. 塊級元素垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰的塊級元素會發生margin合併,不屬於同一個BFC的兩個相鄰的塊級元素不會發生margin合併;
  4. BFC的區域不會與float的元素區域重疊
  5. 計算BFC的高度時,浮動子元素也參與計算
  6. BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素;外面的元素也不會影響到容器裡面的子元素


說了一通BFC的觸發條件和佈局規則,初次接觸的可能很不容易理解;下面用這些BFC佈局規則來舉例幾個常見的css規則和技巧就很容易明白了~



  • 第一點與第二點很好理解,就不舉例子細述了。


  • 外邊距合併是個很常見的問題,即 在垂直方向上的兩個相鄰塊級元素,它們的相鄰一側的外邊距會發生合併(重疊),最終它們倆的間距等於較大的那個外邊距:
<head>
  <style>
    .bro1{
      width:300px;
      height:200px;
      background:#ddd;

      margin-bottom:30px;
    }
    .bro2{
      width:200px;
      height:100px;
      background:pink;

      margin-top:20px;
    }
  </style>
</head>
<body>
  <div class='bro1'></div>
  <div class='bro2'> </div>
</body>

外邊距合併.png

 依據第三點規則:位於同一BFC內的塊級元素會發生外邊距合併;那麼,要解決這個問題,讓原先這兩個相鄰的兩個元素不在同一BFC內就可以了。 為其中一個塊建立新的BFC:

<head>
  <style>
    .bro1{
      width:300px;
      height:200px;
      background:#ddd;

      margin-bottom:30px;
    }
    .bro2{
      width:200px;
      height:100px;
      background:pink;

      margin-top:20px;
    }
    .special{
      overflow:auto;
    }
  </style>
</head>
<body>
  <div class='special'>
    <div class='bro1'></div>
  </div>
  <div class='bro2'> </div>
</body>

效果:
解決外邊距合併.png



  • 第四點:BFC的區域不會與float的元素區域重疊。 就算是初學浮動 應該也知道當元素浮動時會脫離文件流,向一邊流動直到它的邊緣碰到包含框的邊緣;因為不在文件流中所以不佔空間,在浮動時可以覆蓋住別的元素:
    浮動0.png 浮動1.png
     利用第四點的約束規則,可以讓沒有浮動但又不想被覆蓋的元素觸發BFC,就不會給float的元素覆蓋住了。

這個規則還可以作為多欄佈局的一種實現方式。

<body>
  <div id="main">
        <div class="left"></div>
        <div class="right"></div>
        <div class="center"></div>
    </div>
</body>

左右兩欄寬度固定,中間欄可以根據瀏覽器寬度自適應:
多欄佈局.png



  • 包含浮動子元素:因為浮動元素脫離文件流,所以父元素的高度是隻會由包含的非浮動元素決定。特別是如果父元素中所有的子元素都進行了浮動,那麼這個父元素的高度將會為0。
     而要想讓父元素包含住浮動元素,就只要讓父元素觸發BFC就能利用到上面的第六條規則:計算BFC的高度時,浮動子元素也參與計算。 這就是時常用的一個技巧“用overflow:hidden/auto清除包含塊內子元素的浮動”的原理。