Sth about BFC
KongHou

一、什么是 BFC?

BFC(Block Formatting Context,块级格式化上下文) 是 CSS 中非常核心的一个概念。
它是一个独立的渲染区域,在这个区域内的元素布局不会影响到区域外的元素

换句话说,BFC 就像一个“隔离的盒子”,里面的布局规则只在内部生效。


二、BFC 的创建条件

以下元素会创建 BFC:

  1. 根元素(<html>
  2. 浮动元素(float 不为 none
  3. 绝对定位元素(positionabsolutefixed
  4. 表格的标题和单元格(displaytable-captiontable-cell
  5. 匿名表格单元格元素(displaytableinline-table
  6. 行内块元素(displayinline-block
  7. overflow 的值不为 visible 的元素
  8. 弹性元素(display: flexinline-flex 的元素的直接子元素
  9. 网格元素(display: gridinline-grid 的元素的直接子元素

⚠️ 以上为 CSS2.1 规范定义的 BFC 触发方式。
CSS3 规范中,弹性元素和网格元素不再创建 BFC,而是分别创建:

  • FFC(Flex Formatting Context)
  • GFC(Grid Formatting Context)

匿名盒(Anonymous Box)

  • 匿名盒(Anonymous Box) 是浏览器为保证 CSS 视觉格式化模型的完整性而自动生成的临时盒子。
    它们不在 DOM 树中存在,但会出现在渲染树中,参与布局、格式化上下文的创建和计算。
    对于匿名表格盒,出现场景在表格结构缺失标签时,自动补齐 table 层级,会创建 BFC。

三、BFC 的范围

官方定义:
“A block formatting context contains everything inside of the element creating it, that is not also inside a descendant element that creates a new block formatting context.”

翻译过来就是:
BFC 包含创建它的元素的所有子元素,但不包括创建了新 BFC 的子元素内部的元素。

换句话说,一个元素不能同时存在于两个 BFC 中。
子元素如果自己又创建了新的 BFC,那么它的内部就与父级 BFC 隔离开了。

📘 例如:

1
2
3
4
5
<table>
<tr>
<td></td>
</tr>
</table>

假设 table 元素创建的 BFC 记为 BFC_tabletr 元素创建的 BFC 记为 BFC_tr

  • BFC_tr 的范围:td 元素
  • BFC_table 的范围:仅包含 tr 元素(不包括 tr 里面的 td

这就是 BFC 的“层级隔离”特性。


四、BFC 的特性

除了创建一个独立的空间外,BFC 还具备以下五个核心特性:

序号 特性 描述
内部块级盒子垂直排列 BFC 内部的块级元素会在垂直方向一个接一个放置
相邻块级元素的 margin 可能发生折叠 同一 BFC 内相邻块的外边距会折叠,不同 BFC 间则不会
盒子的左边与包含块的左边相接触 即使存在浮动,也会保证块盒子左边缘贴齐包含块左边缘(从右向左布局则相反)
BFC 区域不会与浮动元素重叠 BFC 会避开浮动元素,自动调整位置
计算高度时会包含浮动元素 BFC 内的浮动元素会被纳入高度计算,可用于清除浮动

五、BFC 的常见应用场景

1. 清除浮动(解决高度塌陷)

当父元素内的所有子元素都浮动时,父元素高度会“塌陷”为 0。
解决办法:让父元素创建 BFC。

1
2
3
.parent {
overflow: hidden; /* 触发 BFC */
}

✅ BFC 内的浮动元素会参与高度计算,从而恢复父级高度。


2. 防止外边距折叠

在同一个 BFC 下,两个垂直相邻的块级元素会发生 margin 折叠

1
2
3
4
5
6
.a {
margin-bottom: 20px;
}
.b {
margin-top: 20px;
}

实际间距为 20px,而不是 40px。

解决方法:让其中一个元素创建新的 BFC。

1
2
3
.b {
overflow: hidden; /* 触发 BFC */
}

✅ 不同 BFC 间的 margin 不会折叠。


3. 自适应多栏布局

利用 BFC 的 特性 ③特性 ④

1
2
3
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
1
2
3
4
5
6
7
8
9
10
.left,
.right {
float: left;
width: 100px;
height: 200px;
}
.center {
overflow: hidden; /* 触发 BFC */
background: lightcoral;
}

✅ 中间栏会自动避开左右浮动栏并自适应剩余宽度,实现经典“三栏布局”。


六、BFC 与其他格式化上下文的关系

缩写 全称 说明
BFC Block Formatting Context 块级格式化上下文
IFC Inline Formatting Context 行内格式化上下文
FFC Flex Formatting Context 弹性格式化上下文
GFC Grid Formatting Context 网格格式化上下文

从 CSS3 开始,Flex 和 Grid 各自形成独立的格式化上下文,用以处理复杂的布局规则。


七、现代写法推荐:display: flow-root

现代 CSS 提供了一个更语义化、更安全的写法来创建 BFC:

1
2
3
.container {
display: flow-root;
}

相当于 overflow: hidden 的效果,但不会影响滚动和裁剪,是未来推荐的主流写法。


八、总结

功能 原理 推荐写法
清除浮动 浮动参与高度计算 overflow: hidden / display: flow-root
阻止 margin 折叠 不同 BFC 间 margin 不折叠 overflow: hidden
自适应布局 避开浮动元素 display: flow-root

🧠 一句话总结:

BFC 是 CSS 布局的“隔离层”,让内部布局自成体系,外部不受干扰。


📚 延伸阅读


Powered by Hexo & Theme Keep
Total words 23.5k