z-index失效首要原因是元素未定位:tailwind的z-*类仅对position为relative/absolute/fixed/sticky的元素生效,static下完全被忽略;其次需排查祖先是否触发层叠上下文(如opacity

z-index类写了但完全没反应,先看position有没有设
Tailwind 的 z-* 类只对已定位元素生效。如果元素的 position 是 static(默认值),浏览器直接忽略所有 z-* 类——连解析都不做,更别说渲染了。
- 常见错误:给一个普通
div直接加z-50,没配relative或absolute - Flex/Grid 容器里的子项不会继承父容器的定位能力,每个需要堆叠控制的子元素都得自己声明
position - JS 动态插入的浮层(如 toast、picker)常漏掉
position: fixed或position: absolute,仅靠 class 切换z-*无效 - 临时验证法:在 DevTools 中检查该元素的 Computed 样式,确认
position不是static;加一句relative立刻能测出是否卡在这一步
z-index数值很大却还是被盖住,大概率撞上了“层叠结界”
CSS 的 z-index 只在同一层叠上下文(stacking context)内有效。一旦某个祖先元素触发新上下文,它的所有后代就被锁进独立空间,彼此比大小,但无法和外部同级元素竞争。
- 触发“结界”的常见属性:
opacity小于 1(哪怕opacity-95)、transform非none(包括scale-100、translate-z-0)、filter非none(哪怕blur-sm或opacity-100) - Chrome DevTools 的 Computed 面板搜
stacking context,标为Yes的节点就是结界入口 - 快速验证:临时删掉父级的
opacity-95或scale-100,遮挡消失 → 确认是它干的 - 特别注意:
position: sticky在滚动超出边界后会退化为relative,此时z-index行为可能突变,需实测
tailwind.config.js里改了zIndex配置但没效果
配置不生效不是构建缓存问题,而是写法踩了硬伤。JIT 模式下,只有符合规范的定义才会生成对应 CSS,且必须重启 dev server。
-
extend.zIndex在 Tailwind v3+ 已废弃,写了等于白写 - 数组写法:
zIndex: ['0', '50', '999']→ 规则根本不会生成 - 键名没加引号:
50: '50'→ JS 解析成数字键,可能导致构建时键丢失或顺序错乱 - ✅ 正确写法:
theme: { zIndex: { 'modal-overlay': '60', 'tooltip': '40' } },改完必须手动重启 dev server
用z-[999]或动态拼接class,生产环境大概率失效
z-[999] 看似灵活,实则绕过了 JIT 的静态扫描机制。Tailwind 构建时只提取 content 配置中出现的字面量字符串,动态拼接无法被捕获。
- React 中
class={`z-[${depth}]`}→ 生产构建漏生成对应 CSS,页面直接无样式 - 第三方库(如 Headless UI)注入的 CSS 可能晚于你的 Tailwind 输出,
z-[999]被覆盖 - 没有语义,查问题时完全不知道
z-[999]对应哪个 UI 层级,协作和维护成本飙升 - 硬塞大数字还埋隐患:多个组件各自用
z-50,但语义不同(Toast vs Dropdown),冲突时无法溯源
z-modal-overlay 和隔壁的 z-tooltip 是否处在同一个“世界”里。检查 DOM 路径上有没有无意中触发 opacity、transform 或 filter 的祖先,比反复调大数值管用得多。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











