transform-style: preserve-3d 是实现 3D 翻转的前提,必须设在翻转容器(如 .card)上以维持子元素的三维空间关系;配合 perspective、--rotate-y 变量和 backface-visibility: hidden 才能正确驱动翻转动画。

为什么 transform-style: preserve-3d 是翻转前提
没有它,子元素的 3D 变换会“压平”到父容器平面,卡片正面和背面永远共面,翻转就只是二维缩放或位移。浏览器默认是 transform-style: flat,必须显式设为 preserve-3d 才能让 rotateY 等真正按三维空间计算。
这个属性要加在翻转的容器上(比如卡片外壳 .card),而不是单个面。常见错误是只给 .card__front 或 .card__back 加,结果无效。
-
transform-style: preserve-3d必须作用于有子元素参与 3D 变换的直接父级 - 父级若设置了
overflow: hidden,可能裁剪出 3D 空间外的背面内容,需配合perspective和足够大的容器尺寸 - 不要在
body或全局根元素滥用该属性,它会影响渲染性能
用 --perspective 自定义属性控制景深
透视距离决定翻转的“立体感”强弱:值越小(如 500px),翻转越夸张;越大(如 2000px),越接近平面旋转。硬编码在 CSS 里改起来麻烦,用自定义属性就能动态调整:
.card {
--perspective: 1200px;
perspective: var(--perspective);
}
这样后续只需修改 --perspective 值,整个卡片组的透视效果同步更新。注意:perspective 要设在翻转容器(.card)上,不是 :root —— 否则所有后代都受同一透视影响,容易错乱。
立即学习“前端免费学习笔记(深入)”;
- 不能把
perspective和perspective-origin混用;后者仅影响透视“消失点”位置,非必需 - 如果卡片尺寸变化频繁,
--perspective建议用px或rem,避免用%导致不可预期缩放 - 某些旧版 Safari 对小于
600px的perspective值渲染异常,建议下限设为700px
正反面如何用 --rotate-y 驱动翻转动画
把翻转角度抽成变量,能统一控制状态、支持 JS 切换、也方便做 hover / click 多种触发方式:
.card {
--rotate-y: 0deg;
transform: rotateY(var(--rotate-y));
}
.card.is-flipped {
--rotate-y: 180deg;
}
.card__front {
transform: rotateY(0deg);
}
.card__back {
transform: rotateY(180deg);
}
关键点在于:正面始终 rotateY(0),背面始终 rotateY(180deg),而容器整体绕 Y 轴旋转,让两面在 3D 空间中自然切换可见性。不要试图对正反面分别做 rotateY 动画 —— 那会破坏 preserve-3d 的空间一致性。
- 动画应加在
.card上,用transition: transform 0.4s ease,别加在正反面元素上 - 为防止背面在未翻转时“透出”,给
.card__back加backface-visibility: hidden - 若用 JS 控制,直接操作
element.style.setProperty('--rotate-y', '180deg')即可,无需 class 切换
移动端点击翻转时,touch-action: manipulation 很关键
iOS Safari 默认会对 click 事件加约 300ms 延迟,导致翻转响应卡顿。光靠 cursor: pointer 或 onclick 不够,必须解除延迟:
.card {
touch-action: manipulation;
}
这行声明告诉浏览器:“这个区域只做轻触操作,不用等双击或长按”,从而跳过延迟。但要注意:它仅对支持该属性的浏览器生效(Chrome 36+、Safari 11.1+、Firefox 63+),老版本 iOS 需降级用 fastclick 库或监听 touchstart。
- 别在
body全局设置touch-action: manipulation,否则可能禁用页面滚动 - 如果卡片内含可拖拽区域(如轮播图),不要给该子元素继承此属性,否则拖动手势失效
- 配合
will-change: transform可提升翻转帧率,但仅在频繁交互场景下启用,避免过度触发 GPU
preserve-3d 和 backface-visibility 这两个底层开关一旦漏掉,再漂亮的变量名也救不回白屏或穿模。


















