z-index 无法实现无缝卡片切换动画,因其为离散整数属性不可插值;应改用可过渡的 transform: translateZ()、scale() 等硬件加速属性配合 preserve-3d 和 perspective 控制视觉层叠。

z-index 不能用于实现“无缝卡片切换”动画——它本身不可过渡,写 transition: z-index 0.3s 完全无效,只会导致层叠顺序在动画结束瞬间跳变,视觉上卡顿、错位、遮挡。
为什么 z-index 加 transition 没反应?
浏览器不支持对离散整数属性插值。z-index: 1 到 z-index: 99 中间没有 z-index: 50.5 这种状态,所以过渡被忽略。你看到的“切换”,其实是 transform 动画进行中、但 z-index 还没生效(或已突变)造成的视觉脱节。
- 常见现象:卡片已放大/位移,却仍被隔壁卡片遮住半截,直到动画结束才突然“弹到最前”
- 根本原因:hover 或 class 切换时,
z-index变更和transform动画不同步,且无法同步 - 即使父容器设了
transform-style: preserve-3d,z-index在子元素新层叠上下文中依然不参与过渡
真正能做无缝切换的 CSS 属性只有这些
要让“谁在前、谁在后”的变化看起来是平滑的,必须靠可插值、硬件加速的属性驱动视觉深度感:
-
transform: translateZ():直接控制 Z 轴位置,配合perspective和preserve-3d形成真实 3D 层次 -
transform: scale()+translateZ()组合:单纯scale()只缩放,加translateZ()才产生景深错觉(比如scale(1.1) translateZ(60px)表示“更近更大”) -
opacity:可平滑过渡,常配合缩放/位移强化进出感 -
filter: blur()或box-shadow:辅助营造远近虚实,但别用在高频动画里(性能差)
实际切换时怎么写才不翻车?
关键不是“怎么让 z-index 动起来”,而是“怎么绕过它,用 transform 控制视觉优先级”:
立即学习“前端免费学习笔记(深入)”;
- 所有卡片必须在同一个父容器内,且该父容器**不能有
transform、opacity、filter**(否则会创建隔离的层叠上下文,子元素 z-index 彼此失效) - 父容器设
perspective: 1000px和transform-style: preserve-3d - 每张卡片初始都带
transform: translateZ(0)(哪怕只是 0),避免首帧强制创建合成层导致跳变 - 切换焦点卡时:目标卡设
transform: scale(1.05) translateZ(80px),其余卡统一设transform: scale(0.92) translateZ(-40px),全部只过渡transform - 如果要用 JS 控制,别在
click后立刻读offsetTop或getBoundingClientRect(),改用requestAnimationFrame延迟到下一帧再操作
最容易被忽略的一点:很多人给卡片加 scale(1.2) 就以为“浮起来了”,结果边缘发虚、缩放抖动、Chrome 下尤其明显——这正是因为没加 translateZ(0) 触发 GPU 合成。真正的无缝,藏在 translateZ() 的毫厘偏移里,不在 z-index 的整数跳跃中。


















