抽象的BFC

216 阅读5分钟

在我看来,我觉得BFC是比较抽象的东西,虽然平时经常碰到,但是如果不结合实际例子单单讲概念性的东西,可能很难理解透彻。所以下文将在对BFC有一个基本的认识后引入实例进行讲解。

什么是BFC

BFC(Block Formatting Context)是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。

产生BFC的条件

  • 根元素或其它包含它的元素;
  • 浮动元素,float除none以外的值;
  • 绝对定位元素,position(absolute,fixed);
  • display为以下其中之一的值:inline-block,table-cell;
  • overflow除了visible以外的值(hidden,auto,scroll);
  • 弹性盒布局flex(元素的display: flex或inline-flex)。

最常见的就是overflow:hiddenfloat:left/rightposition:absolute,也就是当我们看到这些属性的时候,就代表了该元素已经创建了一个BFC。

BFC的范围

一个BFC包含创建该上下文元素的所有子元素,但不包括创建了新BFC的子元素的内部元素。

<div id="div_1" class="BFC_1">
    <div id="div_2">
        <div id="div_3"></div>
        <div id="div_4"></div>
    </div>
    <div id="div_5" class="BFC_2">
        <div id="div_6"></div>
        <div id="div_7"></div>
    </div>
</div>

上面的代码表示,#div_1创建了一个块格式上下文BFC_1,这个上下文包括了#div_2#div_3#div_4#div_5。但是由于#div_5创建了BFC_2,所以#div_6,#div_7就被排除在BFC_1之外。

这从另一方角度说明,一个元素不能同时存在于两个BFC中

BFC的效果

  1. 内部的盒子会在垂直方向一个接一个排列(可以看作BFC中有一个常规流);
  2. 计算BFC的高度时,浮动元素也参与计算;
<style>
    .box{
      background:#888;
      height: 100%;
    }
    .div_1{
      background: rgb(248, 52, 248);
      width: 100px;
      height: 200px;
      float: left;
      border: 2px solid #F31264;
    }
    .div_2{
      background: #e0f144;
      width: 100px;
      height: 100px;
      border: 2px solid #F31264;
      opacity: .5;
    }
</style>

<div class="box">
    <div class="div_1"></div>
    <div class="div_2"></div>
 </div>


如图,可以看到,.div_1向左浮动,它创建了一个BFC。同时,由于.box并没有创建BFC,因此在计算高度的时候,并没有考虑.div_1的区域,发生了高度坍塌,这也是我们经常遇到的问题。

现在我们给上面的.box创建一个BFC看看会发生什么。

<style>
    .BFC{
      overflow: hidden;
    }
    .box{
      background:#888;
      height: 100%;
    }
    .div_1{
      background: rgb(248, 52, 248);
      width: 100px;
      height: 200px;
      float: left;
      border: 2px solid #F31264;
    }
    .div_2{
      background: #e0f144;
      width: 100px;
      height: 100px;
      border: 2px solid #F31264;
      opacity: .5;
    }
</style>
    
<div class="box BFC">
    <div class="div_1"></div>
    <div class="div_2"></div>
</div>

.box创建了一个新的BFC后,高度发生了变化,计算高度时它将.div_1区域也考虑进去了。

   3.处于同一个BFC中的元素相互影响,比如经典的垂直外边距塌陷

<style>
    .BFC{
      overflow: hidden;
    }
    .div_1{
      background: #000;
      width: 100px;
      height: 100px;
      margin-bottom: 20px;
    }
    .div_2{
      background: #000;
      width: 100px;
      height: 100px;
      margin-top: 10px;
    }
</style>

<div class="BFC">
    <div class="div_1"></div>
    <div class="div_2"></div>
</div>

在常规文档流中,两个兄弟盒子之间的垂直距离是由他们的外边距所决定的,但不是他们的两个外边距之和,而是以较大的为准。如图:


既然存在这个问题,那有什么办法解决呢?答案是肯定的。先引入另一条BFC的效果(第4):BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,同样外面的元素不会影响到BFC内的元素

所以在这里,我们让.div_1.div_2再处于另一个BFC中就行了。

.BFC{
  overflow: hidden;
}
.div_1{
  background: #000;
  width: 100px;
  height: 100px;
  margin-bottom: 20px;
}
.div_2{
  background: #000;
  width: 100px;
  height: 100px;
  margin-top: 10px;
}

<div class="BFC">
    <div class="BFC">
      <div class="div_1"></div>
    </div>
    <div class="div_2"></div>
</div>

这样就解决了外边距塌陷的问题,如图:

   4.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;

   5.浮动盒区域不叠加到BFC上。

.BFC{
  overflow: hidden;
}
.box{
  background: #3ff18f;
  width:400px;
  min-height: 100px;
}
.div_1{
  background: rgb(248, 52, 248);
  width: 100px;
  height: 100px;
  margin-right: 20px;
  float: left;
  border: 2px solid #F31264;
}
.div_2{
  background: #e0f144;
  width: 100px;
  height: 200px;
  border: 2px solid #F31264;
  opacity: .5;
  float: left;
}

<div class="BFC">
    <div class="div_2"></div>
    <div class="box">
      <div class="div_1"></div>
      <div class="div_1"></div>
      <div class="div_1"></div>
    </div>
</div>


可以看到,由于.box没有创建新的BFC,他内部.div_1块受到了.div_2的影响,被挤到右边去了。现在我们来给.box创建一个新的BFC解决这个问题:

<div class="BFC">
    <div class="div_2"></div>
    <div class="box BFC">
      <div class="div_1"></div>
      <div class="div_1"></div>
      <div class="div_1"></div>
    </div>
</div>


看!现在.box也是一个BFC,不会受到左边.div_2的挤压了,而且也不会发生重叠了。

总结

看到这里,我们也发现了其实这东西无处不在,只是平时经常忽略,没有系统的归纳学习。这次总算是理解得透彻了!

参考文章

学习 BFC (Block Formatting Context)

CSS中的BFC详解