
Stacking Context(堆叠上下文)和 BFC(Block Formatting Context,块格式化上下文)不是同一个概念 ,它们是 CSS 中两个不同的布局与渲染机制,虽然创建条件有部分重叠,但作用和效果完全不同。
一、Stacking Context
堆叠上下文,又称层叠上下文(Stacking Context),是CSS中用于控制元素在Z轴方向堆叠顺序的重要概念。
1.1 定义
堆叠上下文是 HTML 元素在 z轴(垂直于屏幕方向) 上的层叠顺序的上下文环境。它决定了元素在视觉上的前后显示关系。
1.2 主要作用
管理元素在 z 轴上的层叠顺序。
子元素的层叠顺序受限于父堆叠上下文。
影响 z-index 属性的计算和生效。
1.3 创建条件
文档根元素 <html>。
position 属性值非 static,且 z-index 不为 auto。
opacity 的值小于 1,触发透明度合成。
transform、perspective、filter 或 clip-path 属性值不为 none。
设置了 isolation: isolate,创建独立的堆叠上下文。
mix-blend-mode 属性值不同于 normal,启用混合模式。
will-change 指定了上述可能影响层叠顺序的属性。
contain 属性设为 layout 或 paint,限定渲染范围。
作为 Flex 或 Grid 容器的子元素,且其 z-index 值不等于 auto。
注意:此列表尚不完整,有待后续补充完善。
1.4 默认堆叠顺序
同一堆叠上下文内的默认堆叠顺序从下到上
层级顺序 | 堆叠层级描述 | 包含元素类型 |
|---|---|---|
1 | 背景和边框 | 形成堆叠上下文的根元素的背景和边框 |
2 | 负z-index值的定位元素 | z-index为负的定位元素(position: relative/absolute/fixed/sticky) |
3 | 块级盒 | 正常文档流中的块级元素(非定位的块级元素) |
4 | 浮动盒 | 设置了float属性的元素 |
5 | 内联盒 | 正常文档流中的内联元素 |
6 | z-index: 0或auto的定位元素 | 没有明确设置z-index或z-index为0的定位元素 |
7 | 正z-index值的定位元素 | z-index为正的定位元素,值越大层级越高 |

记忆口诀:背景边框 < 负z-index < 块盒 < 浮动盒 < 内联盒 < 定位auto/0 < 正z-index。
二、BFC
BFC,全称为 Block Formatting Context,中文译为“块级格式化上下文”,是CSS中用于描述页面块级元素布局的重要概念。
2.1 定义
BFC 是一个 独立的渲染区域,内部元素的布局不会影响外部元素,外部元素也不会影响内部元素。它主要控制 x轴和 y轴(平面) 上的布局。
2.2 主要作用
解决 margin 折叠问题。
清除浮动(包含内部浮动元素)。
防止元素被外部浮动元素覆盖。
实现两栏自适应布局等。
2.3 创建条件
根元素(<html>)。
float 属性值不为 none。
overflow 属性值非 visible(例如:hidden、auto、scroll)。
采用 position: absolute 或 fixed 定位。
display 属性为 inline-block、flex、grid、table-cell、table-caption、flow-root 等特定值。
注意:此列表尚不完整,有待后续补充完善。
三、核心区别
特性 | Stacking Context | BFC |
|---|---|---|
作用维度 | z轴(层叠顺序) | x/y轴(平面布局) |
主要功能 | 管理元素前后显示关系 | 实现布局隔离和特殊布局效果 |
对 z-index 影响 | 直接影响 z-index 的计算 | 不影响 z-index |
对浮动的影响 | 无直接关系 | 包含内部浮动元素,防止外部浮动覆盖 |
选择技巧:遇到布局问题 → 问自己:
1. 是元素"前后显示"的问题吗?→ 是 → Stacking Context
2. 是元素"位置/尺寸/间距"的问题吗?→ 是 → BFC
四、BFC 主要作用的示例
下是 BFC 四大主要作用的具体代码示例,每个示例都包含 问题状态 和 解决方案,并附带详细注释说明 BFC 的工作原理。
4.1 解决 margin 折叠问题
问题状态(margin 折叠)
.box {
width: 200px;
height: 100px;
background-color: #f0f0f0;
margin: 50px; /* 上下 margin 均为 50px */
}<!-- 两个相邻块级元素,margin 会发生折叠 -->
<div class="box">Box 1</div>
<div class="box">Box 2</div>
<!-- 实际间距:50px(而不是 50px + 50px = 100px) -->解决方案(使用 BFC 阻止折叠)
.box {
width: 200px;
height: 100px;
background-color: #f0f0f0;
margin: 50px;
}
/* 使用 BFC 容器包裹第二个元素 */
.bfc-container {
overflow: hidden; /* 创建 BFC */
}<div class="box">Box 1</div>
<!-- 使用 BFC 容器包裹,阻止 margin 折叠 -->
<div class="bfc-container">
<div class="box">Box 2</div>
</div>
<!-- 实际间距:100px(50px + 50px) -->4.2 清除浮动(包含内部浮动元素)
问题状态(父元素高度坍塌)
.parent {
width: 400px;
background-color: #e0e0e0;
border: 2px solid #333;
/* 未创建 BFC,父元素高度会坍塌 */
}
.child {
width: 150px;
height: 150px;
background-color: #ff6b6b;
float: left; /* 子元素浮动 */
margin: 10px;
}<div class="parent">
<div class="child">浮动子元素 1</div>
<div class="child">浮动子元素 2</div>
</div>
<p>父元素高度坍塌,border 只包裹内容文本</p>解决方案(BFC 包含浮动元素)
.parent {
width: 400px;
background-color: #e0e0e0;
border: 2px solid #333;
/* 使用 BFC 包含浮动子元素 */
overflow: hidden; /* 创建 BFC */
}
.child {
width: 150px;
height: 150px;
background-color: #ff6b6b;
float: left;
margin: 10px;
}<div class="parent">
<div class="child">浮动子元素 1</div>
<div class="child">浮动子元素 2</div>
</div>
<p>父元素高度正常,完全包裹浮动子元素</p>4.3 防止元素被外部浮动元素覆盖
问题状态(元素被浮动覆盖)
.float-box {
width: 200px;
height: 200px;
background-color: #4ecdc4;
float: left; /* 左侧浮动元素 */
margin: 10px;
}
.normal-box {
width: 300px;
height: 300px;
background-color: #ffe66d;
/* 普通元素,会被浮动元素覆盖 */
}<div class="float-box">左侧浮动元素</div>
<div class="normal-box">普通元素 - 被浮动元素覆盖</div>解决方案(BFC 防止覆盖)
.float-box {
width: 200px;
height: 200px;
background-color: #4ecdc4;
float: left;
margin: 10px;
}
.bfc-box {
width: 300px;
height: 300px;
background-color: #ffe66d;
/* 使用 BFC 防止被浮动元素覆盖 */
overflow: hidden; /* 创建 BFC */
}<div class="float-box">左侧浮动元素</div>
<div class="bfc-box">BFC 元素 - 不被浮动元素覆盖</div>4.4 实现两栏自适应布局
问题状态(右侧元素宽度溢出)
.left {
width: 200px;
height: 300px;
background-color: #95e1d3;
float: left; /* 左侧固定宽度 */
margin-right: 20px;
}
.right {
height: 300px;
background-color: #f38181;
/* 普通元素,内容会环绕浮动元素 */
}<div class="left">左侧固定宽度(200px)</div>
<div class="right">右侧普通元素 - 内容环绕浮动元素,宽度未自适应</div>解决方案(BFC 实现两栏自适应)
.left {
width: 200px;
height: 300px;
background-color: #95e1d3;
float: left; /* 左侧固定宽度 */
margin-right: 20px;
}
.right {
height: 300px;
background-color: #f38181;
/* 使用 BFC 实现右侧自适应宽度 */
overflow: hidden; /* 创建 BFC */
}<div class="left">左侧固定宽度(200px)</div>
<div class="right">右侧 BFC 元素 - 自适应剩余宽度,不环绕浮动元素</div>五、Stacking Context 示例(层叠顺序)
为了对比,再补充一个 Stacking Context 的示例,展示其在 z 轴上的层叠控制:
.box {
width: 150px;
height: 150px;
padding: 20px;
position: absolute;
font-size: 18px;
font-weight: bold;
}
.box1 {
background-color: #ff6b6b;
top: 50px;
left: 50px;
z-index: 1; /* 在当前堆叠上下文中层级为 1 */
}
.box2 {
background-color: #4ecdc4;
top: 80px;
left: 80px;
z-index: 2; /* 在当前堆叠上下文中层级为 2,显示在 box1 上方 */
}/* 创建新的堆叠上下文 */
.new-stacking-context {
position: relative;
z-index: 0; /* 创建新的堆叠上下文 */
margin-top: 200px;
background-color: rgba(0, 0, 0, 0.1);
padding: 20px;
}
.box3 {
background-color: #ffe66d;
top: 50px;
left: 50px;
z-index: 100; /* 在新堆叠上下文中层级很高,但不影响外部堆叠 */
}
.box4 {
background-color: #a78bfa;
top: 280px;
left: 80px;
z-index: 5; /* 在根堆叠上下文中层级为 5,显示在 box3 上方 */
}<div class="box box1">Box 1 (z-index: 1)</div>
<div class="box box2">Box 2 (z-index: 2)</div>
<div class="new-stacking-context">
<div class="box box3">Box 3 (z-index: 100, 新堆叠上下文)</div>
</div>
<div class="box box4">Box 4 (z-index: 5)</div>总结
Stacking Context 和 BFC 是 CSS 中两个独立的概念。
虽然部分创建条件重叠(如 position: absolute/fixed),但作用机制完全不同。
Stacking Context 解决层叠显示问题,BFC 解决布局隔离和浮动问题。
彩蛋
本文于 Cnb 平台完整呈现了 CSS BFC 示例代码,欢迎前往阅读《CSS BFC完整示例》以获取详尽内容。