z-index失效主因是元素未参与同一层叠上下文:必须设position为relative/absolute/fixed/sticky;父容器含transform/opacity等会创建新层叠上下文,隔离子元素z-index;响应式断点中激活的此类属性尤需警惕。

z-index 设了却没用,基本可以断定:它压根没进同一个比较场——不是数值不够大,而是被父级“关小黑屋”了。
为什么 z-index 写了等于没写?
最常见原因:position 没设或设错。z-index 只对 position 值为 relative、absolute、fixed 或 sticky 的元素生效;设成 static(默认值)时,浏览器直接忽略 z-index。
- 检查目标元素的
Computed面板里position是否为预期值,不是static - 动态插入的 DOM(如 JS 创建的 toast)必须显式加
position: relative,否则z-index形同虚设 -
position: sticky在滚动超出边界后会退化为relative,此时z-index行为可能突变
为什么 Chrome 正常,Safari 里弹窗就被盖住?
iOS Safari 对 transform 和 opacity 极其敏感:哪怕只是 transform: translateZ(0) 或 opacity: 0.99,它就立刻创建新层叠上下文,把子元素的 z-index 锁死在局部范围。
- 真机打开 Safari 开发者工具 → Elements 面板逐级点父节点 → 右侧 Layout 标签页看
Stacking context是否标为Yes - 重点盯住模态框的直接父容器、轮播外层、卡片包装器——这些地方常偷偷加了
transform做动画或硬件加速 - 临时给可疑父容器加
position: relative; z-index: 0;(注意:z-index: 0必须配position才生效)
为什么响应式断点一开,z-index 就失效?
媒体查询里激活的 transform、filter、will-change 或 opacity 是最大嫌疑。例如 @media (max-width: 768px) { .hero { transform: scale(1); } } —— 这个 scale(1) 就足以触发新层叠上下文。
- 切到对应断点,在 DevTools 的
Computed面板搜transform,看是否从none变成了具体值 - 别只改子元素的
z-index,先确认它的**最近定位父容器**是否参与全局排序;该容器本身就得有z-index - 避免在断点中只改
position却漏掉z-index:移动端切position: fixed时,必须同步加z-index
Tailwind 中 z-50 不生效,是配置错了还是写法错了?
Tailwind v3+ 的 zIndex 必须用对象语法明确定义,且改完要重启 dev server;z-[999] 动态拼接在构建时不会被扫描,生产环境必漏。
- 正确写法:
zIndex: { 'modal-overlay': '60', 'tooltip': '40' }(键名必须是字符串,不能是modal-overlay或数字) - 错误写法:
extend: { zIndex: { ... } }(无效)、zIndex: ['0', '10'](已废弃)、class="z-[${depth}](不生成 CSS) - 所有涉及
z-类的组件,必须用预定义的语义名(如z-modal-overlay),而非硬编码数字或运行时拼接
真正难的不是算清哪个元素该写多少,而是每次加 transform、改 opacity 或切断点时,都要往上多看两层 DOM,确认那个刚被激活的属性没把你需要突出的元素关进盒子。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











