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完整示例》以获取详尽内容。