z-index 只对已定位元素生效,必须配合 position: relative(或非 static)创建层叠上下文;否则即使设 z-index 也会被忽略,子元素还可能脱离预期位置。

必须同时满足两个条件:父容器设 position: relative(或其它非 static 值),子元素设 position: absolute + z-index。只写 z-index 不生效,只写 position: absolute 但没定位上下文会“飞走”。
为什么只加 z-index 没用
z-index 是个“懒属性”——它只对已定位元素起作用。默认 position: static 的元素,无论 z-index 设成 9999 还是 -9999,浏览器直接忽略。
- 检查元素的
Computed面板,看position真实值是不是static - 常见误写:
z-index: 10;却漏掉position: relative;或类似声明 - 即使父级有
z-index,子级没定位,照样不参与层叠比较
父容器必须设 position: relative
这是最常被跳过的一步。不设它,position: absolute 的子元素会一路向上找最近的已定位祖先;找不到就落到 <html> 上,结果就是元素飘到视口左上角。
- 只需在父容器加
position: relative;,无需额外z-index - 不要依赖
display: inline-block或float来“模拟”定位上下文——它们不创建层叠上下文 - 如果父容器本身已有
position: absolute或fixed,也 OK,但要小心嵌套层级带来的层叠上下文隔离
z-index 的值不是越大越好
数值本身没上限,但真正决定谁在上的,是「层叠上下文」内的相对大小。一个 z-index: 1 的子元素,永远盖不住它父级的 z-index: 999 ——因为子元素被锁死在父级的层叠上下文中。
立即学习“前端免费学习笔记(深入)”;
- 先确认两个要比较的元素是否处于同一层叠上下文(即有没有中间某层用了
opacity: 0.99、transform、will-change等触发新上下文的属性) - 避免无意义地堆高数字,比如从 10 改成 999999 ——只要比兄弟元素大 1 就够了
- 负值合法(如
z-index: -1),但会让元素沉到父容器背景之下,慎用
替代方案:transform: translateZ(1px)
当不需要真实脱离文档流、又想视觉上“浮起”时,这个技巧更轻量。它不改变布局,也不依赖定位上下文,但要注意副作用。
- 它靠 GPU 渲染层实现覆盖,适合动画或性能敏感场景
- 底层元素仍可被点击,需手动加
pointer-events: none阻断交互 - 在 iOS Safari 中,配合
position: fixed可能出现渲染错位,优先用position: absolute+z-index组合 - 调试时 DOM 树看不出层级变化,容易误判,建议仅用于明确知道需求的场合
真正卡住人的往往不是 z-index 数值,而是某个中间父级悄悄创建了新层叠上下文,或者开发者工具里看到的 position 值其实是继承/计算后的结果,不是你写的那行 CSS。



















