结论

元素重叠时的显示先后由层叠顺序决定,从底到顶依次是:background 和 border、z-index 为负的元素、块级元素、浮动元素、内联元素、z-index 为 0 或 auto 的元素、z-index 为正的元素。z-index 只在同一个层叠上下文内部可比。

最后更新:2026-09-17 · 基于 CSS 2.1 视觉格式化模型附录 E 的层叠规则

二、堆叠上下文

1. 堆叠顺序

深入理解CSS中的层叠上下文和层叠顺序

“层叠顺序”英文称作”stacking order”. 表示元素发生层叠时候有着特定的垂直显示顺序,叠顺序规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
显 示 器
+-------------------+ <-----+ 装 饰
| background/border|
| +----------------------+
| | 负 z-index |
+-----+ +-----------------------+
| | div/块 级 元 素 | <---+ 布 局
| | +-----------------------+
+----+ | float浮 动 元 素 |
| | +-----------------------+
+--+ |inline/inline-block盒子 | <--+ 内 容
+-+ +------------------------+
| | z-index:0/z-index:auto |
+--+ +------------------------+
+-+ 正 z-index |
+------------------------+

用 户 眼 睛

从用户的眼睛到显示之间堆叠的顺序依次:

  1. 正z-index
  2. z-index:0/z-index:auto(position:relative)
  3. inline/inline-block元素
  4. float浮动元素
  5. 块级元素
  6. 负z-index
  7. border
  8. background

1.1 borderbackground上的例子

当边框的颜色设置透明度时,背景色改变,视觉上边框的颜色也变了,说明borderbackground上。

1
2
3
4
5
6
7
8
9
<style>
div {
border: 10px solid rgba(255,0,0, 0.2);
width: 300px; height: 200px;
background: green;
/*background: yellow; */
}
</style>
<div></div>

1.2 说明div块元素在border上的例子

可以看见子div把父div的border覆盖了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
.dad {
border: 10px solid rgba(255,0,0, 1);
width: 300px; height: 200px; background: green;
}
.son {
width: 70px; height: 20px;
background: blue; color: black;
margin-left: -5px;
}
</style>
<div class="dad">
父元素
<div class="son"></div>
</div>

父div中内联元素与字div中内联元素发生堆叠,后面覆盖前面的

下面的例子中,父div中内联元素由于在子div中内联元素的前面,所以被覆盖了, 同级的元素也是后面的覆盖前面的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
.dad {
border: 10px solid rgba(255,0,0, 1);
width: 300px; height: 200px;
background: green; color: red;
}
.son {
width: 70px; height: 20px;
background: blue; color: black;
margin-top: -10px;
}
.son1 {
color: yellow; margin-bottom: -10px;
}
</style>
<div class="dad">
父元素
<div class="son"> 子元素 </div>
<div class="son1 son">子元素</div>
父元素
</div>

1.3 说明float浮动元素在div上的例子

在这个例子中,浮动元素覆盖了div元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
.dad {
border: 10px solid rgba(255,0,0, 1);
width: 300px; height: 200px; background: green;
text-indent: -10px;
}
.son {
width: 70px; height: 20px;
background: yellow; color: black;
margin-left: -5px;
}
.float {
width: 50px; height: 50px; background: blue;
float: left;
}
</style>
<div class="dad">
父元素
<div class="float"></div>
<div class="son"></div>
</div>

1.4 说明内联元素在float浮动元素上面的例子

可以看见内联元素在浮动元素的上面。

内联元素也比浮动元素中的内联元素靠前(在前面)。

浮动元素中的内联元素优先级是没有外边的内联元素优先级高。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<style>
.dad {
border: 10px solid rgba(255,0,0, 1);
width: 300px; height: 200px; background: green;
text-indent: -20px;
}
.float {
width: 50px; height: 50px; background: blue;
float: left; color: red;
}
</style>
<div class="dad">
父元素
<div class="float">浮动元素</div>
</div>

1.5 z-index的值大于等于0的元素在内联元素的上面

z-index的值是auto相当于0。

z-index属性只能给position的值是relativeabsolutefixed设置才会生效。

在下面的例子中,z-index的值大于等于0的元素覆盖在内联元素上面。

z-index的值大的覆盖小的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<style>
.dad {
border: 10px solid rgba(255,0,0, 1);
width: 300px; height: 200px; background: #ccc;
}
.float {
width: 50px; height: 150px; background: blue;
float: left; color: red;
}
.relative {
width: 150px; height: 20px;background: yellow;
position: relative;
margin-top: -10px;
}
.absolute {
width: 50px; height: 60px;background: green;
position: absolute; margin-top: -10px;
z-index: 1;
}
.rel {z-index: 1; margin-top: 0;background: white}
</style>
<div class="dad">
11
<div class="float"></div>
<div class="relative"></div>
<div class="absolute"></div>
<div class="relative rel"></div>
</div>

1.6 z-index的值为负数的元素在background的后面

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
.dad {
border: 10px solid red; width: 300px; height: 100px; background: #ccc;
}
.negative {
width: 50px; height: 150px;background: green;
position: absolute;
z-index: -1;
}
</style>
<div class="dad">
<div class="negative"></div>
</div>

2. 层叠上下文(堆叠上下文)

mdn层叠上下文介绍

层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。

满足下面任何一个条件就会触发层叠上下文:

  • 根元素 (HTML),
  • z-index 值不为 “auto”的 绝对/相对定位,
  • position: fixed
  • 一个 z-index 值不为 “auto”的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
  • opacity 属性值小于 1 的元素(参考 the specification for opacity),
  • transform 属性值不为 “none”的元素,
  • mix-blend-mode 属性值不为 “normal”的元素,
  • filter值不为“none”的元素,
  • perspective值不为“none”的元素,
  • isolation 属性被设置为 “isolate”的元素,
  • 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
  • -webkit-overflow-scrolling 属性被设置 “touch”的元素

层叠上下文主要影响z-index的属性。

从上面的条件中可以看见,一个网页会有一个默认的层叠上下文(根元素 HTML),当元素发生堆叠的时候:

  1. 从元素往上找,找到父辈中触发了层叠上下文的元素,没有就是根元素。
  2. 两个父辈触发层叠上下文的元素比较堆叠优先级,高的子元素在上面。
  3. 如果父辈元素堆叠优先级相同,后面的覆盖前面的。
  4. 如果他们的触发层叠上下文的父辈元素时同一个,那么就按照层叠顺序堆叠。

在下面的例子中:

  1. 父元素的层叠上下文优先级相同时,那么b1覆盖a1,
  2. 把a元素的层叠上下文优先级变大,那么b1则在整个a元素下面。
  3. 如果a元素和b元素同时修改为z-index:zuto,那么a1元素在b1元素上面。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<style>
/*http://js.jirengu.com/fogij/8/edit*/
.dad { width: 300px; height: 200px; background: #ccc; }
.negative {
width: 150px; height: 70px;background: green;
position: relative;
}
.a1,.b1 {
width: 100px; height: 20px;background: yellow;
position: relative;
}
.a1 {z-index: 10;}
.b1 {background: blue; margin-top: -55px; z-index: 0;}
.a { z-index: 2; }
.b { z-index: 2; width: 170px; background: white;}
</style>
<div class="dad">
<div class="negative a">a
<div class="a1">a1</div>
</div>
<div class="negative b">b
<div class="b1">b1</div>
</div>
</div>

常见问题

为什么 z-index 设成 9999 还是压不住别的元素

因为 z-index 只在同一个层叠上下文里比较。如果你的元素所在的父级创建了一个新的层叠上下文,而那个父级本身的层级低于目标元素,子元素设多大都跳不出去。要改的是父级的层级,不是子元素的。

哪些属性会创建新的层叠上下文

根元素 html、position 为 relative/absolute 且 z-index 不为 auto、position 为 fixed 或 sticky、opacity 小于 1、transform、filter、will-change 等都会创建。opacity 和 transform 最容易被忽略,因为它们看起来跟层级无关。

z-index 为负的元素会跑到哪里

会跑到常规流的块级元素后面,但仍在所属层叠上下文的 background 和 border 之前。所以给子元素设 z-index: -1 时,它会被父元素的背景遮住而不是显示在下层。