z-index: auto 与 z-index: 0 的本质区别在于是否创建新的层叠上下文:auto 不创建,0 会创建;前者子元素参与全局层叠比较,后者使子元素层级被限制在父容器内部。

z-index: auto 和 z-index: 0 都不显式设数值,但行为差异根源在层叠上下文创建
关键判断:两者在**是否创建新的层叠上下文(stacking context)** 上有本质区别。这不是“谁层级更高”的问题,而是“是否切断了与父级 z-index 的比较链”。z-index: auto 不触发新层叠上下文;z-index: 0 会——哪怕值为 0,只要不是 auto,且元素已定位(position 为 relative/absolute/fixed),就立即成为独立的层叠结界。
什么时候 z-index: 0 会“突然失效”?看它是否意外隔离了子元素
典型现象:给父容器设了 z-index: 0,子元素设 z-index: -1,结果子元素没被父容器盖住,反而浮在上面。这不是 bug,是层叠上下文生效了:z-index: 0 让父容器成了一个独立 stacking context,子元素的 z-index: -1 只在该 context 内部起作用,对外不可见;而父容器整体的堆叠层级,只由它自己的 z-index(即 0)和兄弟元素比。
- 若父容器没设
z-index(即默认auto),子元素z-index: -1会和同级其他定位元素直接比,可能被遮盖 - 若父容器设了
z-index: 0,子元素z-index: -1就只在父容器内部“下沉”,但父容器本身仍处于文档流中靠后的位置,可能被后出现的兄弟元素覆盖 - 想让子元素真·沉底,要么去掉父容器的
z-index,让子元素参与全局排序;要么把父容器z-index设得足够低(如-1),并确保它不创建不必要的 context(但z-index: -1依然会创建 context)
z-index: auto 的真实含义不是“等于 0”,而是“不参与创建”
z-index: auto 是初始值,它不赋予具体数字,也不创建层叠上下文。它的层叠等级取决于所处上下文:在根层叠上下文中,它等效于 0 级别,但这个“0”是被动继承来的,不是主动声明的。所以:
- 两个相邻的
position: relative; z-index: auto元素,谁在 HTML 里写在后面,谁就盖在上面(后来者居上) - 一个
z-index: auto元素和一个z-index: 0元素在同级,它们在层叠顺序上无天然高低之分,仍按 DOM 顺序决定覆盖关系 - 但一旦
z-index: 0元素内部有子元素,这些子元素的z-index就只跟它爹比,不再和外部任何元素比——这是最常被忽略的隔离效应
调试时怎么一眼看出谁创建了层叠上下文?
浏览器开发者工具不会直接标出“此元素创建了 stacking context”,但可通过以下线索快速定位:
立即学习“前端免费学习笔记(深入)”;
- 检查元素 computed 样式中
z-index值:如果是数字(含 0、-1),且position !== static,基本可判定创建了 context - 注意那些看似没设
z-index却“异常抗压”的元素——可能父级或祖先级有z-index非auto值,已提前切分了上下文 -
opacity: 0.99、transform: translateZ(0)、will-change: transform等属性也会创建层叠上下文,和z-index无关,但效果类似:隔离子元素层级
真正难处理的从来不是 z-index 数值大小,而是你根本没意识到某个 z-index: 0 已经悄悄把整个子树关进了独立的 z 轴牢房。


















