z-index 不能过渡,因其属非可动画属性,浏览器不插值仅跳变;应改用 transform 和 opacity 实现视觉层级切换效果。

z-index 本身不能过渡,写 transition: z-index 0.3s 是无效的——浏览器根本不会插值计算,只会“啪”一下跳变。这不是 bug,是规范行为。
为什么 z-index 不能加 transition
z-index 属于「非可动画属性」(non-animatable property),CSS 动画规范明确将其排除在 transition 和 @keyframes 支持列表之外。即使你写了 transition: all 0.3s,z-index 部分也静默失效,不报错、不警告、不插值。
- 浏览器只对 opacity、transform、color 等明确支持插值的属性做帧间计算
- z-index 的作用是参与层叠上下文排序,不是视觉状态,没有中间值概念
- DevTools 的 Computed 面板里,
transition-property显示为z-index,但实际 timeline 中看不到任何过渡曲线
替代方案:用 transform + opacity 模拟层级切换
真正可过渡、且能达成“视觉上从下到上浮现”效果的,只有 transform 和 opacity。它们既能触发 GPU 加速,又支持平滑插值。
- 把需要“弹出”的元素设为
position: absolute或fixed,初始opacity: 0、transform: scale(0.95) translateY(10px) - 激活时改
opacity: 1、transform: scale(1) translateY(0),配合transition: opacity 0.2s ease, transform 0.2s ease - 如果必须强调“压过其他内容”,就同步提升其父容器的
z-index(比如从10→100),而不是试图过渡子元素的 z-index
容易踩的坑:误以为 z-index 变化会带动渲染顺序渐变
即使你用 JS 在每帧手动修改 z-index 值(比如从 10 → 20 → 30),视觉上也不会看到“慢慢浮上来”的过程——它总是在 layout 阶段一次性重排层叠顺序,没有中间态。
立即学习“前端免费学习笔记(深入)”;
- 不要用
requestAnimationFrame循环改 z-index,纯属浪费性能 - 别在
@keyframes里写z-index: 100; ... z-index: 999;,动画播放时该值只在起始和结束帧生效 - 若需响应式层级控制(比如 tooltip 随鼠标靠近逐渐“顶出”),靠的是 visibility + transform 动画,不是 z-index 数值渐变
真正要动的从来不是 z-index 的数字,而是它所处的层叠上下文位置——要么抬高父容器,要么把元素挪到更高上下文(如挂到 body 下),再配以可动画属性实现视觉过渡。


















