在css布局中,当多个元素通过position进行定位并发生重叠时,我们通常使用z-index来控制它们的叠放次序。不过实际写代码时,经常会遇到设了z-index却不起作用的情况,这背后有一些必须留意的规则。

z-index生效的前提条件
z-index并不是一个可以随便写在任意元素上的属性。它只对定位元素有效,也就是说元素的position值必须是relative、absolute、fixed或sticky,并且z-index需要设置为一个整数(包括0和负数)。如果元素position为static,哪怕写了z-index也会被浏览器忽略。
.box {
position: absolute; /* 必须是定位元素 */
z-index: 10; /* 数值才生效 */
}
.static {
position: static;
z-index: 999; /* 无效,不会被应用 */
}
层叠上下文对比较范围的限制
很多人以为z-index是全局比大小,其实元素只在同一个层叠上下文中比较。一旦某个父元素创建了层叠上下文,它的子元素无论z-index多大,都只能在父级内部排次序,无法越级盖住外部元素。
常见创建层叠上下文的方式
- 设置position为非static且z-index为数值
- 使用opacity小于1
- 使用transform、filter、perspective等属性
- flex或grid容器的子项设了z-index
示例说明
下面代码中,父容器创建了层叠上下文,内部子元素z-index再高也超不出父容器范围:
<div style="position:relative; z-index:1;"> <div style="position:absolute; z-index:9999;">子元素</div> </div> <div style="position:absolute; z-index:2;">外部元素</div>
虽然子元素z-index是9999,但外部元素z-index为2且和父容器同上下文,外部元素仍会显示在父容器及其子元素之上。
负值与自动堆叠
z-index可以取负值,这时元素会跑到普通流内容后面,常用来做背景装饰。另外未设z-index的定位元素默认按出现顺序叠放,后写的在上层。
| 场景 | 表现 |
|---|---|
| 同上下文无z-index | 后写覆盖先写 |
| z-index为负 | 低于普通流内容 |
| 不同上下文 | 先比父上下文层级 |
调试建议
当叠放异常时,先检查元素是否定位、z-index是否数值,再沿dom树向上看是否有祖先意外创建了层叠上下文。用浏览器审查面板能直接看到computed里的z-index和上下文关系。
记住:z-index管的是同一层叠上下文内的次序,而不是整个页面的绝对层级。
掌握这些注意点,就能在写弹窗、下拉菜单、遮罩层时少踩坑,让界面层级符合预期。