CSS中的BFC,是什麼?

一、常見定位方案

普通流
    預設,從上而下,行內元素水平排列,行滿換行,塊級元素渲染成一個新行。
浮動
    先按普通流位置出現,然後根據浮動方向偏移。
絕對定位
    元素具體位置由絕對定位座標組成。

二、什麼是BFC

BFC(Block Formatting Context)格式化上下文,是Web頁面中盒模型佈局的CSS渲染模式,指一個獨立的渲染區域或者說是一個隔離的獨立容器。

BFC 即 Block Formatting Contexts (塊級格式化上下文),屬於普通流。 可以把 BFC 理解為一個封閉的大箱子,箱子內部的元素無論如何翻江倒海,都不會影響到外部。

三、形成BFC的條件

  1、浮動元素,float 除 none 以外的值; 
  2、絕對定位元素,position(absolute,fixed); 
  3、display 為以下其中之一的值 inline-block,table-cell,table-caption、flex; 
  4、overflow 除了 visible 以外的值(hidden,auto,scroll);
  5、body 根元素

四、BFC的特性

 1、內部的Box會在垂直方向上一個接一個的放置。
 2、垂直方向上的距離由margin決定
 3、bfc的區域不會與float的元素區域重疊。
 4、計算bfc的高度時,浮動元素也參與計算
 5、bfc就是頁面上的一個獨立容器,容器裡面的子元素不會影響外面元素。

五、例項講解

1、BFC中的盒子對齊

特性的第一條是:內部的Box會在垂直方向上一個接一個的放置。
<template>
  <div id="app">
    <!-- 1、BFC中的盒子對齊 -->
    <div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
        <div class="box3"></div>
        <div class="box4"></div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
/* 1、BFC中的盒子對齊 */
 div {
    height: 20px;
}
.container {
    position: absolute;  /* 建立一個BFC環境*/
    height: auto;
    background-color: #eee;
}
.box1 {
    width: 400px;
    background-color: red;
}
.box2 {
    width: 300px;
    background-color: green;
}
.box3 {
    width: 100px;
    background-color: yellow;
    float: left;
}
.box4 {
    width: 200px;
    height: 30px;
    background-color: purple;
}
</style>

效果:

1.png

浮動的元素也是這樣,box3浮動,他依然接著上一個盒子垂直排列。並且所有的盒子都左對齊。

2、外邊距摺疊

特性的第二條:垂直方向上的距離由margin決定
也會用到第五條特性: bfc就是頁面上的一個獨立容器,容器裡面的子元素不會影響外面元素。

在常規文件流中,兩個兄弟盒子之間的垂直距離是由他們的外邊距所決定的,但不是他們的兩個外邊距之和,而是以較大的為準。

<template>
  <div id="app">
    <div class="container">
        <div class="box1"></div>
        <div class="box2"></div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
.container {
  overflow: hidden;
  width: 100px;
  height: 100px;
  background-color: red;
}
.box1 {
  height: 20px;
  margin: 10px 0;
  background-color: green;
}
.box2 {
  height: 20px;
  margin: 20px 0;
  background-color: green;
}
</style>

效果:

2.png


這裡我們可以看到,第一個子盒子有上邊距(不會發生margin穿透的問題);兩個子盒子的垂直距離為20px而不是30px,因為垂直外邊距會摺疊,間距以較大的為準。

那麼有沒有方法讓垂直外邊距不折疊呢?答案是:有。特性的第5條就說了:bfc就是頁面上的一個獨立容器,容器裡面的子元素不會影響外面元素,同樣外面的元素不會影響到BFC內的元素。所以就讓box1或box2再處於另一個BFC中就行了。

<template>
  <div id="app">
    <!-- 特性的第5條:bfc就是頁面上的一個獨立容器,容器裡面的子元素不會影響外面元素,同樣外面的元素不會影響到BFC內的元素。 -->
    <div class="container">
      <div class="wrapper">
        <div class="box1"></div>
      </div>
      <div class="box2"></div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
/* 特性的第5條:bfc就是頁面上的一個獨立容器,容器裡面的子元素不會影響外面元素,同樣外面的元素不會影響到BFC內的元素。
   .container建立一個BFC環境
   .wrapper建立一個BFC環境
*/
.container {
  overflow: hidden;
  width: 100px;
  height: 100px;
  background-color: red;
}
.wrapper {
  overflow: hidden;
}
.box1 {
  height: 20px;
  margin: 10px 0;
  background-color: green;
}
.box2 {
  height: 20px;
  margin: 20px 0;
  background-color: green;
}
</style>

效果:

3.png


3、不被浮動元素覆蓋

以常見的兩欄佈局為例。

左邊固定寬度,右邊不設寬,因此右邊的寬度自適應,隨瀏覽器視窗大小的變化而變化。

如果要是不加bfc的話就會被遮蓋

<template>
  <div id="app">
    <!-- 3、不被浮動元素覆蓋  -->
    <div class="column"></div>
    <div class="column"></div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
/* 3、不被浮動元素覆蓋 
 .column:nth-of-type(2) 建立一個BFC環境
 :nth-of-type(n) 選擇器匹配屬於父元素的特定型別的第 N 個子元素的每個元素.
 */
.column:nth-of-type(1) {
  float: left;
  width: 200px;
  height: 300px;
  margin-right: 10px;
  background-color: red;
}
.column:nth-of-type(2) {
  overflow: hidden;
  height: 300px;
  background-color: purple;
}
</style>

效果:

4.png


還有三欄佈局。

左右兩邊固定寬度,中間不設寬,因此中間的寬度自適應,隨瀏覽器的大小變化而變化。

<template>
  <div id="app">
      <!-- 三欄佈局 -->
    <div class="contain">
      <div class="column"></div>
      <div class="column"></div>
      <div class="column"></div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
/* 三欄佈局 */
.column:nth-of-type(1),
.column:nth-of-type(2) {
  float: left;
  width: 100px;
  height: 300px;
  background-color: green;
}
.column:nth-of-type(2) {
  float: right;
}
.column:nth-of-type(3) {
  overflow: hidden;
  height: 300px;
  background-color: red;
}
</style>

效果:

5.png


也可以用來防止字型環繞:

眾所周知,浮動的盒子會遮蓋下面的盒子,但是下面盒子裡的文字是不會被遮蓋的,文字反而還會環繞浮動的盒子。這也是一個比較有趣的特性。

<template>
  <div id="app">
    <!-- 字型環繞 -->
    <div class="left"></div>
    <p>你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
       你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
       你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好
    </p>
  </div>
</template>
<script>
export default {
  name: 'App',
  data(){
    return {
      
    }
  },
  methods:{
    
  }
}
</script>
<style scoped>
/* 字型環繞 p標籤加不加bfc,實現不同效果 (overflow: hidden;) */
.left {
  float: left;
  width: 100px;
  height: 100px;
  background-color: yellow;
}
p {
  background-color: green;
  /* overflow: hidden; */
}
</style>

P標籤不加BFC實現效果:

6.png

P標籤加BFC實現效果:

7.png

4、BFC包含浮動的塊

利用overflow:hidden清除浮動,因為浮動的盒子無法撐出處於標準文件流的父盒子的height。

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

浮動的元素會脫離普通文件流,來看下下面一個例子:

 <!-- 4 BFC包含浮動的塊 -->
<div style="border: 1px solid #000;">
     <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
 </div>

效果:

8.png


由於容器內元素浮動脫離文件流,導致容器只剩下2px邊距高度,我們這時候可以採用BFC:

<div style="border: 1px solid #000;overflow: hidden">
    <div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>

效果:

9.png


tags:#CSS#BFC