z-index不是权重,只在同层叠上下文中生效;失效时先查父容器是否意外创建上下文(如opacity

z-index 不是“权重”,它只在同一个层叠上下文中生效;所谓“按权重重叠”,本质是搞清谁和谁比、在哪比。
z-index 失效时,先查父容器有没有偷偷创建层叠上下文
两个 position: absolute 元素设了 z-index: 10 和 z-index: 20,但视觉上没变化——大概率它们压根不在同一层叠上下文中比较。
- 打开浏览器开发者工具,在 Elements 面板里逐级检查两个元素的父容器,看是否意外设置了:
opacity: 0.99、transform: translateZ(0)、filter: blur(1px)、will-change: transform或z-index(非auto) - 这些属性都会触发新层叠上下文,一旦触发,子元素的
z-index就只在该父容器内起作用,跨不过去 - 临时删掉这些属性验证:如果层级恢复正常,说明问题就出在这里
- 若必须保留效果(比如需要
transform做动画),就把两个需要比高低的absolute元素提级到同一个「干净」父容器下——即该父容器不带任何触发层叠上下文的属性
没设 z-index 的 absolute 元素,默认按 HTML 源码顺序堆叠
当两个同级 position: absolute 元素都没设 z-index(或都设为 auto),它们的层叠顺序由 DOM 出现先后决定:后写的盖在先写的上面。
- 这个规则在静态 HTML 中可靠,但在 Vue/React 动态渲染、
v-if或ngIf条件插入时容易失效——DOM 插入时机可能和预期不符 - 不要依赖“写在后面就一定在上面”,尤其涉及 JS 控制显示/隐藏时
- 只要需要稳定顺序,就必须显式设
z-index,哪怕只是z-index: 1和z-index: 2 -
z-index: auto等价于0,但它不创建新层叠上下文;对普通子元素来说,它只是“不干预”,不影响同级比较
z-index 数值本身没有“权重含义”,只有相对大小和上下文边界
设 z-index: 9999 并不能穿透低层级的层叠上下文。它的作用范围被严格限制在所属上下文内部。
- 一个
z-index: 9999的弹窗,如果父容器有opacity: 0.8,那它永远盖不过另一个z-index: 1但处于根层叠上下文(比如直接挂 body 下)的遮罩层 - 真正起决定作用的是:父容器自身的层叠等级(由其自身是否创建上下文 + 其
z-index值共同决定) - 常见分层惯例:
z-index: 10(背景)、100(内容区)、999(弹窗)、1000(全屏模态框),但前提是它们都在同一上下文,或父级上下文层级合理 - 避免滥用超大数值(如
99999),它掩盖结构问题,调试时反而更难定位冲突源
absolute 元素必须有已定位的祖先,否则定位基准不可控
如果两个 absolute 元素的父容器都没设 position: relative(或其他非 static 值),它们会一路向上找,最终可能都相对于 body 或视口定位——导致位置漂移、重叠区域错位,看起来像“层级混乱”,实则是定位基准失控。
- 确保所有参与叠加的
absolute元素,其最近的已定位祖先(通常是直接父容器)设了position: relative - 这个父容器本身不能触发意外层叠上下文(见第一条)
- 如果多个
absolute元素要精确重叠,最好共用同一个relative父容器,而不是分散在不同分支下 - 移动端慎用
will-change: transform,它会强制创建合成层,可能额外引入上下文且影响性能
最常被忽略的点不是 z-index 本身,而是层叠上下文的嵌套层级——它像一道隐形墙,把 z-index 的影响力锁死在墙内。调层级前,先画出 DOM 树里每一层是否创建了上下文,比盲目调数字更有效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











