z-index: 9999没用是因为元素未定位(position为static)或被父级层叠上下文隔离;必须设position为relative/absolute/fixed/sticky,并检查opacity<1、transform非none等是否隐式创建新上下文。

z-index: 9999 没用,不是数字不够大,而是它根本没生效,或者生效了但被锁死在某个“小房间”里——这个房间由某个父级悄悄创建,子元素再高的 z-index 都出不去。
元素没定位,z-index 直接被浏览器忽略
这是最常被跳过的前提。z-index 对 position: static(默认值)完全无效,哪怕你写了 z-index: 9999,DevTools 的 «Computed» 面板里 z-index 仍显示为 auto,position 也还是 static。
- 打开 Chrome DevTools → 选中被遮挡元素 → «Computed» 面板搜索
position,确认计算值是relative、absolute、fixed或sticky - 临时加
position: relative(不位移、不影响布局),如果遮挡立刻消失,就坐实是这问题 - flex / grid 子项虽可直接写
z-index,但前提是父容器是 flex 或 grid,且该子项本身未被祖先层叠上下文隔离
父级偷偷建了“玻璃罩”:层叠上下文(stacking context)
即使目标元素已定位、z-index 计算值也正确,只要它的任意一个祖先(不一定是直接父级)触发了层叠上下文,整个子树就被关进独立空间——z-index: 9999 只能跟同房间里的兄弟比,够不到外面的导航栏或弹窗。
- 触发层叠上下文的常见属性:
opacity小于 1(opacity: 0.99也触发)、transform不是none(包括transform: translateZ(0)、scale(1))、filter不是none(哪怕filter: blur(0))、will-change: transform、isolation: isolate、position: fixed或sticky且z-index不为auto - 用 DevTools 快速定位:选中被遮挡元素 → «Layout» 标签页看
Stacking context是否为Yes;点击右侧Show stacking context,高亮区域就是“玻璃罩”边界 - 逐级点击父节点,在 «Computed» 里搜
transform、opacity、filter,第一个非默认值就是源头
子元素 z-index 再高,也突破不了父容器的“天花板”
子元素的 z-index 只决定它在父容器内部的顺序,对外它只继承父容器在整个页面中的层级位置。比如父容器 z-index: 10,子元素写 z-index: 9999,它依然压不过另一个 z-index: 20 的同级容器。
立即学习“前端免费学习笔记(深入)”;
- 修复方向不是堆数字,而是提升“关住它”的那个父容器本身的
z-index(例如设为z-index: 1050) - 如果父容器必须保留
transform(如动画需要),就给它同步加position: relative和足够高的z-index - 对
modal、tooltip类组件,更彻底的解法是用 portal(React)或 teleport(Vue)把元素挂到<body>下,绕过所有祖先上下文
overflow: hidden 是裁剪,不是遮挡,但效果一样骗人
这个和 z-index 无关,但常被误判为“被盖住”。当父容器设了 overflow: hidden(或 auto、scroll)且子元素是 position: absolute 并超出边界时,浏览器会在绘制前直接裁掉内容——层叠顺序根本没机会参与。
- 检查被遮挡元素是否“突然消失”而非“被盖住”,比如下拉菜单只显示一半、弹窗顶部被切掉
- 临时删掉父级的
overflow: hidden,看内容是否完整出现 - 若必须保留裁剪,改用
clip-path或调整子元素定位范围,而不是硬调z-index
真正难排查的,往往不是某一行 CSS 写错了,而是 DOM 树上隔了三四层的一个 transform: scale(1) 或 opacity: 0.99 —— 它们看起来毫无杀伤力,却无声切断了整个 z 轴层级链。


















