translateZ 是唯一能真正沿 Z 轴移动元素的 CSS 属性,但需父容器设 transform-style: preserve-3d 且避免 overflow: hidden 或意外层叠上下文干扰。

translateZ 是唯一能真正推开 Z 轴的属性
CSS 的 transform 里,translateZ() 不是“视觉错觉”,它真把元素沿 Z 轴移动——前提是父容器有 transform-style: preserve-3d,且自身没被扁平化(比如没触发层叠上下文或被 transform 以外的属性意外重置)。
常见错误现象:translateZ(100px) 完全没效果,卡片还是贴在一起;或者所有卡片突然“消失”——大概率是父容器漏了 preserve-3d,或用了 overflow: hidden 把伸出 Z 轴的部分裁掉了。
- 必须给直接父容器加
transform-style: preserve-3d,不能只加在最外层 wrapper 上 -
perspective要加在父容器上(不是每个卡片),值太小(如100px)会让 Z 移动剧烈变形,太大(如5000px)又几乎看不出层次,建议从800px起调 - 避免在卡片上用
position: absolute同时又设z-index——Z 轴位移和 z-index 混用会冲突,优先靠translateZ()控制前后关系
卡片堆叠顺序由 translateZ 值大小决定
数值越大,卡片越“靠近你”;负值则推远。但注意:这不是 z-index 的叠加顺序,而是真实空间坐标。所以 translateZ(200px) 的卡片,即使 DOM 顺序在最后,也会盖住 translateZ(100px) 的卡片——只要它们共用同一个 3D 空间上下文。
使用场景:做展开动画时,常让中间卡片 translateZ(200px),两侧依次递减(150px、100px),形成扇形展开。但别用等差硬套:人眼对近处深度更敏感,建议用非线性衰减,比如 [200, 160, 120, 80] 比 [200, 150, 100, 50] 更自然。
立即学习“前端免费学习笔记(深入)”;
- 不要依赖 DOM 顺序控制遮挡——一旦加了
preserve-3d,Z 坐标说了算 - 如果某张卡片始终被盖住,检查它是否被祖先元素的
transform(比如scale(0.99))无意中触发了新层叠上下文,导致脱离 3D 空间 - 移动端 Safari 对负
translateZ渲染不稳定,尽量用正向位移 + perspective 配合
rotateY + translateZ 是展开动画的核心组合
纯 translateZ 只能前后平移,要做出“翻页式”展开,必须配合 rotateY()。关键点在于:旋转中心默认是元素中心,但卡片堆叠时,我们希望绕着整个堆叠体的中心轴转——所以得用 transform-origin: center center -200px 把旋转原点拉到 Z 轴后方。
性能影响:rotateY 和 translateZ 都是合成属性(composited),不会触发布局或绘制,但若同时改 top/left 或写入 opacity,就可能降级为软件渲染。
- 动画中优先用
transform+opacity,避免width/height/margin -
transform-origin的第三个参数(Z 偏移)只在preserve-3d下生效,且单位必须是 px,不能是 % - Chrome 115+ 对高帧率 3D 动画做了优化,但 Safari 仍建议将动画时长控制在 300–400ms 内,避免卡顿感明显
调试时先确认 3D 空间是否真正建立
最常被忽略的一步:打开浏览器开发者工具的“Rendering”面板(Chrome / Edge),勾选 Show 3D view。如果看不到分层结构,说明 3D 空间根本没起来——不是代码写错了,就是某个中间容器悄悄加了 transform: none 或 will-change: transform 以外的触发条件。
另一个信号是:鼠标悬停卡片时,transform 值在 Elements 面板里实时变化,但视觉无反应。此时右键检查该元素,看 Computed 标签页里 transform-style 是否为 flat(而非 preserve-3d)。
- 用
getComputedStyle(el).transformStyle在控制台手动验证,比肉眼判断可靠 - 某些 CSS-in-JS 库(如 styled-components)会自动注入
transform: translateZ(0)来强制硬件加速,这反而会破坏你的 3D 层级——得显式覆盖掉 - Firefox 的 3D 视图不如 Chrome 直观,调试优先用 Chrome










