z-index无效主因是元素未参与层叠计算或被父级层叠上下文限制;需确保position非static、检查祖先是否创建新层叠上下文(如opacity

z-index写了却没用,几乎从不因为数值太小,而是元素根本没参与层叠计算,或者被父级“关进小房间”里了——那个房间叫层叠上下文(stacking context)。
元素的 position 是不是 static
浏览器直接忽略 z-index,只要元素的 position 是 static(默认值)。这不是“效果弱”,是彻底不读。
- 用 Chrome DevTools 选中目标元素,在 «Computed» 面板搜
position,确认最终值不是static - 临时加一行
position: relative(不影响布局),立刻验证z-index是否生效 - JS 动态插入弹层时,常只设
z-index,漏掉同步设置position: fixed或position: absolute -
display: flex或grid容器的子项,即使没写position,也能响应z-index,但仅限该容器内;仍受祖先层叠上下文限制
哪个父级在静默创建 stacking context
只要某个祖先满足以下任一条件,它就强制创建新层叠上下文,子元素的 z-index 只能在它内部比大小,无法和外部同级元素竞争:
-
opacity小于 1(哪怕opacity: 0.999) -
transform不为none(包括transform: translateZ(0)、scale(1)、rotate(0.0001deg)) -
filter不为none(哪怕filter: blur(0)) -
will-change: transform或will-change: opacity isolation: isolate-
position: fixed或sticky且z-index不是auto -
z-index: 0(注意:它会创建新上下文,而z-index: auto不会)
调试建议:
- 在 DevTools Elements 面板中逐级点击父节点,右侧面板 «Layout» 标签页看 «Stacking context» 是否突然变成
Yes - 临时注释掉父级的
transform或opacity,遮挡是否立刻消失?是 → 就是它 - 打开 «Rendering» 面板 → 勾选 «Show layers panel» → 切换到 «Layers» 标签页,直接看到每个层叠上下文对应的 DOM 节点
Tailwind CSS 中 zIndex 配置无效
Tailwind v3.0+ 已废弃数组写法,zIndex 必须完整定义在 theme.zIndex 下,键名必须加引号、值必须是字符串。错一个字符,CSS 规则根本不会生成。
- 只写
extend: { zIndex: { 'modal': '50' } }——theme.zIndex默认为空,追加无效 - 写成
modal: 50(数字)或modal(未加引号),JS 解析失败或截断 - 改完配置后没重启开发服务器 —— Tailwind 不热重载配置变更
- 别用
z-[999]或动态拼接 class:class={`z-[${depth}]`}在构建时不会被扫描,生产环境极易漏生成
✅ 正确示例:
module.exports = {
theme: {
zIndex: {
'background': '0',
'dropdown': '30',
'tooltip': '40',
'modal-overlay': '60',
'modal-content': '70',
}
}
}
iOS Safari 的 body 和 html 特殊限制
iOS Safari 对 body 和 html 极其敏感:html { transform: translateZ(0) } 这种写法会在整个页面顶层建一个强上下文,把所有后续 z-index 全锁死在里面。
-
body { overflow: hidden }→ 导致position: fixed元素滚动时被裁切 - 只要父容器有
transform、opacity 或filter,iOS Safari 就可能忽略position: fixed的语义,让它退化为absolute - 修复优先级:先删
body和html上的transform、filter、opacity,再查具体组件
真正难的不是算清哪个值该写多少,而是每次改样式或媒体查询时,都要往上多看两层 DOM,确认那个刚被激活的 transform 或 opacity 没把你需要突出的元素关进盒子。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











