🧑🏫 作者:全栈老李
📅 更新时间:2025 年 4 月
🧑💻 适合人群:前端初学者、进阶开发者
🚀 版权:本文由全栈老李原创,转载请注明出处。
大家有没有遇到过这样的场景:明明给元素设置了z-index:9999
,但它还是被其他元素压在下面?今天全栈老李就来扒一扒这个让无数前端工程师头疼的问题背后的机制——层叠上下文(Stacking Context)。
什么是层叠上下文?
想象一下,你的网页就像一叠透明胶片,每张胶片上都有不同的内容。层叠上下文就是决定这些胶片叠放顺序的规则。当浏览器渲染页面时,它会按照特定规则决定哪些元素应该显示在前面,哪些应该被遮挡。
全栈老李举个通俗的例子:就像公司组织架构图,不同部门(层叠上下文)之间有大致的层级关系,而部门内部又有自己的职级排序。你不能直接拿一个基层员工去和另一个部门的总监比级别高低。
为什么z-index会失效?
很多同学以为z-index
是个绝对的值,越大就越靠前。但实际上,z-index
只在同一个层叠上下文中比较才有意义。这就好比:
- 你在A部门是经理(z-index:10)
- 我在B部门是总监(z-index:5)
- 但B部门整体层级比A部门高
结果就是我的z-index:5还是能压在你的z-index:10上面
哪些属性会创建层叠上下文?
全栈老李给大家整理下常见的创建层叠上下文的属性:
- 根元素
<html>
-
position: relative/absolute/fixed
+z-index
不为auto -
position: fixed
(即使没有z-index) -
opacity
小于1 -
transform
不为none -
filter
不为none -
will-change
指定了上述属性 isolation: isolate
<div class="parent">
<div class="child1">我会被压在下面</div>
</div>
<div class="sibling">我会显示在最上面</div>
<style>
.parent {
position: relative;
z-index: 1; /* 创建层叠上下文 */
opacity: 0.9; /* 这也创建层叠上下文 */
}
.child1 {
position: absolute;
z-index: 9999; /* 只在.parent内部有效 */
}
.sibling {
position: relative;
z-index: 2; /* 比.parent高 */
}
/* 全栈老李提示:这里的child1虽然z-index很大,但受限于parent的层叠上下文 */
</style>
层叠顺序规则
在同一个层叠上下文中,元素的堆叠顺序(从下到上)是:
- 层叠上下文的根元素
-
position: absolute/relative
且z-index
为负的元素 - 普通流中的块级元素
- 浮动元素
- 普通流中的行内元素
-
position: absolute/relative
且z-index:auto
的元素 -
position: absolute/relative
且z-index
为正的元素
全栈老李发现很多同学容易忽略的是:即使没有设置z-index
,定位元素默认也会比普通元素高!
实际应用场景
模态框被遮挡问题
<div class="modal" style="position: fixed; z-index: 100;">
我是模态框
</div>
<div class="ad" style="position: fixed; z-index: 999;">
我是广告
</div>
这时候模态框会被广告遮挡,因为它们在同一个层叠上下文(根上下文)中比较。解决方法是为模态框创建一个新的更高层级的层叠上下文:
<div class="modal-wrapper" style="position: fixed; z-index: 1000;">
<div class="modal" style="position: absolute; z-index: 1;">
我是模态框
</div>
</div>
<div class="ad" style="position: fixed; z-index: 999;">
我是广告
</div>
动画元素突然"跳"到前面
全栈老李经常看到有同学做动画时遇到元素突然跳到前面的问题,这通常是因为动画中使用了transform
或opacity
,意外创建了新的层叠上下文。
调试技巧
Chrome DevTools现在可以直接查看层叠上下文了:
- 打开Elements面板
- 选中元素
- 在Computed面板搜索"stacking"
- 会显示该元素是否创建了层叠上下文
课后作业
来道面试题练练手吧!以下代码中,各个div的显示顺序是什么?把你们的答案写在评论区,全栈老李会随机抽几位同学的答案进行点评哦~
<div style="position:relative; z-index:1;">
<div style="position:absolute; z-index:100;">A</div>
</div>
<div style="position:relative; z-index:2;">
<div style="position:absolute; z-index:50;">B</div>
</div>
<div style="position:relative; z-index:0;">
<div style="position:absolute; z-index:200;">C</div>
</div>
<div style="opacity:0.99;">
<div style="position:absolute; z-index:300;">D</div>
</div>
记住,理解层叠上下文的关键是要先看元素属于哪个上下文,再比较同一上下文内的z-index。全栈老李建议大家多动手实践,毕竟CSS这东西,光看是看不明白的,得真刀真枪地调试才能掌握!
我是全栈老李,一个资深Coder!
写码不易,如果你觉得有用,点赞 + 收藏 + 关注 走一波!感谢鼓励!🌹🌹🌹