理解BFC

403 阅读4分钟

一、定义

BFC全称是Block Formatting Context,即块格式化上下文。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。通俗一点来讲,触发BFC就是将触发的区域当作一个容器,,这个容器管理着里面的块级元素。BFC内部元素与与外部元素相互隔离,从而使内外元素的定位不会相互影响。

二、触发方式

  • 根元素或其它包含它的元素
  • 浮动 (元素的float不为none)
  • 绝对定位元素 (元素的position为absolute或fixed)
  • 行内块inline-blocks(元素的 display: inline-block);
  • 表格单元格(元素的display:table-cell,HTML表格单元格默认属性)
  • overflow的值不为visible的元素
  • 弹性盒 flex boxes (元素的display: flex或inline-flex)

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

举个例子:

<div class="BFC1 div1">
    <div class="div2"></div>
    <div class="div3"></div>
    <div class="div4">
        <div class="div5 BFC2">
            <div class="div6"></div>
            <div class="div7"></div>
        </div>
    </div>
</div>

div2、div3、div4、div5都属于BFC1创建的格式化上下文,但由于div5也触发了新的BFC,所以div6、div7属于BFC2的格式化上下文,而不属于BFC1的。
也就是说,一个元素不能同时存在于两个BFC中。

三、触发效果

元素触发BFC后,会形成一个与外元素隔离的容器,容器内部会有以下特性:

  • 内部的元素会在垂直方向放置,即块级元素独占一行
  • 浮动的元素不会与BFC区域重叠
  • 处于同一BFC中的元素可能会相互影响,产生margin的重叠
  • 计算BFC高度时,浮动元素也参与计算
  • 触发BFC后会形成一个独立的容器,内外元素互不影响

实例

1、垂直方向的margin重叠

<style>
.div1{
  width:100px;
  height:100px;
  background-color:red;
  margin-bottom:100px;
}
.div2{
  width:100px;
  height:100px;
  background-color:blue;
  margin-top:100px;
}
</style>
<body>
  <div class="div1"></div>
  <div class="div2"></div>
</body>  

代码效果:

image.png

理论上两个div垂直方向应该相差200px的,但实际上发生了margin重叠,只有100px。我们可以利用“一个元素不能同时存在于两个BFC中”来解决这个问题,也就是让他们其中一个触发BFC,从而使两个div不再同一个BFC中,就不会发生margin重叠。

<style>
.div1{
  width:100px;
  height:100px;
  background-color:red;
  margin-bottom:100px;
}
.div2{
  width:100px;
  height:100px;
  background-color:blue;
  margin-top:100px;
}
.box1{
    overflow:hidden;
}
</style>
<body>
  <div class="div1"></div>
  <div class="box1">
    <div class="div2"></div>
  </div>
</body> 

效果图:

image.png

2、父子元素margin重叠

<style>
.box{
width:100px;
height:100px;
background:grey;
}
.wrap {
  background:aqua;

}
.wrap h1{
  background:pink;
  margin:40px;
}
</style>
<body>
<div class="box">box</div>
<div class="wrap">
  <h1>h1</h1>
</div>
</body>

效果图:

image.png

原本h1上下有颜色的margin不见了同时h1和box有40px的距离,如何解决呢?和上面的情况一样,只要触发wrap的BFC使其变成一个独立的容器就行了,比如在wrap的css加上overflow:hidden

效果图:

image.png

3、BFC不会重叠浮动元素

当我们使用浮动元素时,浮动元素会与其他元素重叠,如下:

<style>
.div1{
  height: 100px;
  width: 100px;
  float: left;
  background: lightblue;
}
.div2{width: 200px;
  height: 200px;
  background: #eee;
}
</style>
<body>
<div class="div1">div1</div>
<div class="div2">div2</div>
</body>

image.png

但如果我们不希望他们重叠,则可以利用BFC的效果,触发div2的BFC,让他们不重叠的排列。比如在div2加个overflow:hidden

image.png

我们也可以利用这个特性,来做到两栏自适应布局。

4、父容器高度坍塌问题

<style>
.box1{
  width:100px;
  height:100px;
  float:left;
  border: 2px solid black;
}
.box2{
  width:100px;
  height:100px;
  float:left;
  border: 2px solid black;
}
.box{
  background:aqua;
}
</style>
<body>
<div class="box">
  <div class="box1"></div>
  <div class="box2"></div>
</div> 
</body>

效果图:

image.png

咋一看没什么问题,但实际上父级的高度为0,所以颜色背景没有展现出来。解决的方法同上面讲的一样,触发BFC,使其存在于一个独立的容器,比如加上overflow:hidden

image.png

以上就是关于BFC的分析。
如果您觉得我的文章有用,欢迎点赞和关注,也欢迎光临我的个人博客 github.com/BokFang