块级格式化上下文,更常见的说法是 BFC,BFC 是一块独立的渲染区域,它规定了在该区域中常规流块盒的布局。 在前面我们介绍块盒的时候,介绍过常规流下块盒的很多具体规则,比如常规流块盒水平方向必须撑满包含块,比如常规流块盒按照垂直方向依次摆放,比如常规流块盒的外边距合并,比如常规流块盒的自动高度会无视浮动元素。这些具体的规则其实都是 BFC 规定的。 既然 BFC 是一个区域,那么什么区域是 BFC 呢? 比较常见的有以下几个:
- 根元素
- 浮动元素
- 绝对定位和固定定位元素
- overflow 不为 visible 的元素
在以上元素的内部均会创建 BFC,或者说其内部均为 BFC 区域。其实我们可以认为,BFC 是元素的一种属性,我们可以认为,以上元素均被添加上了 BFC 这样一个属性。
除了上面几个以外,还有一些元素也会创建 BFC,但是并不常见,所以不涉及。
一个 BFC 就是一个独立的渲染区域,多个 BFC 区域之间渲染起来互不干扰。说的更具体一点,创建了 BFC 的元素,或者说带有 BFC 这样一个属性的元素,其内部就是一个独立渲染的区域,即内部和外部被隔绝开了,内部的渲染不会影响到外部。 接下来是创建 BFC 元素的具体规则
- 创建了 BFC 的元素,自动高度需要计算浮动元素
- 创建了 BFC 的元素,border-box 不会和浮动元素重叠
- 创建了 BFC 的元素,不会和他的子元素进行外边距合并
这里一个一个解释,首先,我们知道,在常规流布局中,自动高度的计算是看不到其内部的浮动元素的,但是如果这个元素创建了 BFC,那么这个时候其自动高度就能够看到其内部的浮动元素了。其实从这里我们就可以看到,如果一个元素创建了 BFC,那么这个元素就可以看到其内部的浮动元素,前面其实我们提到了一个问题,就是元素浮动后,其父元素作为常规流布局,是看不到浮动元素的,或者说,浮动元素无法撑开父元素,这种问题叫做高度坍塌。前面提到,我们要解决这个问题,可以使用伪元素来清除浮动,但是这里提供了一种新思路,那就是父元素触发 BFC。一般来说,使用 overflow 来触发 BFC,是解决该问题影响最小的操作。
实际上,要解决高度坍塌最好用的还是伪元素清除浮动的方式。
然后是第二点,我们知道,在常规流布局下的块盒是会无视浮动流的,所以在排列的时候,是会和浮动流元素进行重叠的,但是如果一个元素创建了 BFC,那么这个元素就不会再和浮动元素出现重叠,会自动避开浮动元素。
实际上是通过强制设置 margin-left 进行避开的
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.float {
float: left;
background-color: aqua;
width: 100px;
height: 100px;
}
.test {
background-color: blue;
height: 500px;
}
</style>
</head>
<body>
<div class="float"></div>
<div class="test"></div>
</body>
</html> 显然,此时常规流块盒由于看不到浮动盒子,所以在布局的时候,就会和浮动盒子进行重叠。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.float {
float: left;
background-color: aqua;
width: 100px;
height: 100px;
}
.test {
background-color: blue;
height: 500px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="float"></div>
<div class="test"></div>
</body>
</html>此时给常规流盒子添加上 overflow:hidden,触发了 BFC,此时这个常规流盒子就会自动设置 margin-left 来避开浮动元素。 
对于一边固定,一边宽度自适应的两栏布局,可以使用这种方式,这也是很常见的布局方式,当然,这种效果如果使用 CSS 3 的伸缩盒其实很容易实现。
对于前面的第三点,其实就是不同 BFC 元素的外边距是不能合并的。相信不需要解释。