先记住这个答案
负 z-index 的定位元素,画在它所属层叠上下文根元素的背景和边框之上,画在同一上下文里所有普通流内容之下。关键在于「所属」:如果父元素没有创建层叠上下文,子元素属于更外层的上下文,比如根元素 html,那它就会排到父元素背景的后面,看起来像消失了。想让它留在父元素背景之上、文字之下,给父元素加 isolation: isolate 或者 position: relative; z-index: 0。
- 负层级仍受父级层叠上下文约束
- 父元素不是层叠上下文,子元素会沉到父元素背景后面
isolation: isolate可隔离负层级- 负
z-index必须配合定位才生效
装饰背景的标准写法
最常见的场景是用 ::before 给按钮或卡片做一层渐变、倾斜的背景,要求它在文字下面。
.button {
position: relative;
isolation: isolate; /* 关键:自己创建层叠上下文 */
background: #fff;
}
.button::before {
content: '';
position: absolute;
inset: 0;
z-index: -1; /* 在按钮背景之上、按钮文字之下 */
background: linear-gradient(90deg, #6366f1, #ec4899);
transform: skewX(-12deg);
}去掉 isolation: isolate 再看,渐变层会整个消失。因为 .button 此时只是一个 z-index: auto 的定位元素,不创建层叠上下文,::before 的 -1 是拿到外层上下文里去比的,它被排到了外层上下文的负值层。而 .button 自己是定位元素,它的白色背景画在外层上下文靠上的定位层里,正好把渐变层整个盖住。
加上 isolation: isolate 以后,.button 自己成了层叠上下文的根,-1 只在按钮内部生效,排在按钮白底之上、按钮文字之下。
负 z-index 在层叠顺序里的位置
一个层叠上下文内部,浏览器从下往上依次画:根元素的背景和边框,负 z-index 的后代,普通流里的块级盒,浮动盒,行内内容,z-index 为 auto 或 0 的定位元素,最后是正 z-index 的后代。
负 z-index 排在第二层,这意味着它只比上下文根的背景高,比其他所有东西都低。同一个上下文里有多个负值时,-2 在 -1 下面;数值相同就按文档顺序,后面的盖前面的。
- 为什么根元素背景永远压不住
- 层叠上下文的根元素是把整个上下文当作一张画布来画的,先画它自己的背景,再在上面画后代。所以后代的
z-index再小,也不可能跑到根元素背景下面。这就是「父元素创建了层叠上下文,子元素负z-index就不会跑到父元素后面」的原因。
容易答错的地方
- 以为负
z-index就是全页面最底层 - 它只是所在层叠上下文的底层。一个弹窗内部的元素设
z-index: -9999,也只会沉到弹窗背景之上,不会跑出弹窗去。 - 没加定位就写负
z-index - 普通的静态元素设置
z-index不起作用。至少要position: relative,或者是 flex、grid 容器的子项,z-index才会被采用。 - 忘了它可能接不到点击
- 负
z-index元素被同一上下文里的普通流兄弟盖住以后,鼠标事件会落在上面那层。用它做可点击的背景图、背景视频按钮时,经常出现点了没反应,其实是被别的块挡住了。
面试官还会怎么问?
isolation: isolate 和 z-index: 0 有什么区别?
两者都能创建层叠上下文。z-index: 0 需要元素本身是定位元素或 flex、grid 子项,而且会让元素参与外层上下文里 z-index: 0 那一层的排序,可能改变它和兄弟元素的覆盖关系。isolation: isolate 不要求定位,也不用碰 z-index,只起「封口」作用。对本来就是定位元素、z-index 为 auto 的按钮来说,加上它以后在外层的覆盖关系不变,副作用最小。
哪些属性会让父元素意外变成层叠上下文?
除了定位加数值 z-index,还有 opacity 小于 1、transform、filter 不为 none、position: fixed 或 sticky、will-change 指定了这些属性、contain: paint 等。项目里负 z-index 突然「又能显示了」或者「又消失了」,通常是父元素加减了其中一个属性。
为什么不直接给文字一个更高的 z-index,而要用负值?
文字是普通流内容,要给它 z-index 就得包一层再定位,结构更复杂。装饰层只有一个,把它压下去比把所有内容抬起来省事,也不影响按钮内部其他元素原有的层级。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。