perspective必须作用于父容器而非卡片本身,正确做法是在最近的、包含正反面的祖先容器(如.card-container)上设置perspective值(推荐800px–1200px),以创建3D渲染上下文;同时卡片(.card)需设transform-style: preserve-3d,正反面均需backface-visibility: hidden并用translateZ对齐Z轴位置。

perspective 属性必须作用在父容器上,不是卡片本身
很多人一上来就给 .card 加 perspective: 1000px,结果完全没 3D 效果——这是因为 perspective 不是给要翻转的元素设的,而是给它的**最近的、有变换子元素的祖先容器**设的。它定义的是“观察者离屏幕多远”,类似相机镜头的位置。
正确做法是套一层 wrapper:
<div class="card-container">
<div class="card">
<div class="card-front">正面</div>
<div class="card-back">背面</div>
</div>
</div>
.card-container 设 perspective: 1000px,.card 才能真正感知到 3D 空间。
- 值太小(如
200px)会导致翻转时形变夸张、边缘拉伸严重 - 值太大(如
5000px)会让旋转看起来像 2D,缺乏纵深感 - 不要用
transform: perspective(1000px)替代属性——它只影响自身,不创建 3D 渲染上下文
rotateY 翻转必须配合 transform-style: preserve-3d
即使加了 perspective,如果 .card 没开 transform-style: preserve-3d,它的子元素(.card-front 和 .card-back)依然会在扁平化后绘制,背面永远不可见——这是最常被忽略的一环。
立即学习“前端免费学习笔记(深入)”;
关键样式链:
.card-container { perspective: 1000px; }
.card { transform-style: preserve-3d; transition: transform 0.6s ease; }
.card.is-flipped { transform: rotateY(180deg); }
.card-front, .card-back { position: absolute; backface-visibility: hidden; }
-
backface-visibility: hidden必须加在前后两面,否则翻转 180° 后会看到背面内容的镜像(文字反向) - 没有
preserve-3d,rotateY就只是平面旋转,不会触发真正的 Z 轴空间计算 - 某些旧版 Safari 需要
-webkit-transform-style: preserve-3d前缀
卡片正反面需绝对定位 + 占满容器,且初始 Z 偏移要对称
如果不手动控制 Z 轴位置,前后两面会重叠在同一个平面,翻转时看不到切换效果。必须让正面在 Z=0,背面在 Z=0 但先绕 Y 轴转 180°,再拉回 —— 更稳妥的做法是显式设置 transform: translateZ(…)。
.card-front { transform: rotateY(0deg) translateZ(150px); }
.card-back { transform: rotateY(180deg) translateZ(150px); }
-
translateZ(150px)的值应略小于perspective值(比如perspective: 1000px→translateZ: 150px),保证透视自然 - 两面都设相同
translateZ,才能保证翻转中心在卡片中点;若只给背面设,正面会“飘”在前面 - 必须设
width/height或inset: 0让两面撑满父容器,否则内容会坍缩
交互触发翻转时,注意 transform 会覆盖原有 rotateY
如果卡片已有其他旋转(比如倾斜动画),直接用 transform: rotateY(180deg) 会把之前的 rotateX 或 scale 全干掉。要用 rotateY() 追加,而不是替换。
推荐方案是用 CSS 自定义属性动态组合:
.card {
transform: rotateX(var(--rx, 0deg)) rotateY(calc(var(--ry, 0deg) + var(--flip, 0deg))) scale(var(--s, 1));
}
.card.is-flipped { --flip: 180deg; }
- 直接写多个
rotateY无效(CSS transform 函数不叠加,后声明覆盖前声明) - JavaScript 切换 class 是最稳妥的,避免内联 style 覆盖 :hover 或其他状态
- 移动端要注意
touch-action: manipulation防止点击延迟影响翻转响应
rotateY 本身,而是 perspective 该挂哪、preserve-3d 忘开、或者正反面 Z 轴没对齐——这三处错一个,效果就全废。


















