核心原理
要实现 3D 翻转,你需要理解以下几个关键的 CSS3 属性:

(图片来源网络,侵删)
-
perspective(透视)- 作用:定义了观察者与 3D 空间之间的距离,没有透视,3D 变换看起来就是扁平的 2D 缩放。
perspective的值越小,透视效果越强烈,物体变形越明显。 - 应用位置:通常设置在父容器(.scene)上,它为整个 3D 场景提供了观察的视点。
- 作用:定义了观察者与 3D 空间之间的距离,没有透视,3D 变换看起来就是扁平的 2D 缩放。
-
transform-style: preserve-3d- 作用:这是一个至关重要的属性,它告诉浏览器,其子元素应该在真正的 3D 空间中进行渲染,而不是被扁平化,如果缺少这个属性,你的翻转卡片将只会看起来像是在原地缩放。
- 应用位置:设置在需要进行 3D 变换的元素的直接父容器(.card)上。
-
transform(变换)- 作用:这是执行实际变换的属性,对于翻转效果,我们主要使用:
rotateY(): 绕 Y 轴(垂直轴)旋转,实现左右翻转。rotateX(): 绕 X 轴(水平轴)旋转,实现上下翻转。
- 应用位置:设置在需要翻转的子元素(.card-front, .card-back)上,我们将其中一个面(例如背面)旋转 180 度,使其一开始就“背对着”我们。
- 作用:这是执行实际变换的属性,对于翻转效果,我们主要使用:
-
transition(过渡)
(图片来源网络,侵删)- 作用:让 CSS 属性的变化(如
transform的变化)有一个平滑的动画效果,而不是瞬间完成。 - 应用位置:通常设置在需要进行翻转的元素(.card)上,这样当它应用
transform时,动画就会生效。
- 作用:让 CSS 属性的变化(如
分步实现:一个 3D 翻转卡片
我们将创建一个经典的卡片翻转效果:鼠标悬停时,卡片会翻转显示背面的内容。
HTML 结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">CSS3 3D 翻转卡片</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="scene">
<div class="card">
<!-- 卡片正面 -->
<div class="card-face card-face-front">
<h2>你好,前端!</h2>
<p>这是卡片的正面。</p>
</div>
<!-- 卡片背面 -->
<div class="card-face card-face-back">
<h2>背面世界</h2>
<p>这是卡片的背面,鼠标移开即可返回。</p>
</div>
</div>
</div>
</body>
</html>
结构解析:
.scene: 3D 场景的容器,负责设置perspective。.card: 卡片本身,负责设置transform-style: preserve-3d和transition,并作为翻转的载体。.card-face: 卡片的两个面(正面和背面),它们是.card的直接子元素。.card-face-front: 正面内容。.card-face-back: 背面内容。
CSS 代码 (style.css)
/* --- 基础重置和场景设置 --- */
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: sans-serif;
}
/* 1. .scene: 3D 场景,设置透视效果 */
.scene {
width: 250px;
height: 350px;
perspective: 1000px; /* 关键:设置观察距离,值越小效果越夸张 */
}
/* 2. .card: 卡片容器,是3D变换的主体 */
.card {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* 关键:告诉子元素在3D空间中渲染 */
transition: transform 0.8s; /* 关键:为transform属性添加平滑过渡效果 */
}
/* 3. 鼠标悬停时,让整个卡片绕Y轴旋转180度 */
.scene:hover .card {
transform: rotateY(180deg);
}
/* 4. .card-face: 卡片的两个面 */
.card-face {
position: absolute; /* 关键:让两个面重叠在一起 */
width: 100%;
height: 100%;
backface-visibility: hidden; /* 关键:隐藏元素的背面,防止翻转时看到镜像内容 */
border-radius: 10px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-size: 24px;
color: white;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
/* 5. 设置正面的样式 */
.card-face-front {
background-color: #3498db;
}
/* 6. 设置背面的样式,并先将其旋转180度,使其一开始就“背对着”我们 */
.card-face-back {
background-color: #e74c3c;
transform: rotateY(180deg); /* 关键:让背面初始状态就是翻转后的 */
}
/* 可选:为卡片添加一些交互反馈 */
.card-face-front:hover, .card-face-back:hover {
cursor: pointer;
}
代码解析:
.scene: 设置了固定的宽高和perspective: 1000px,定义了我们观察这个 3D 场景的窗口。.card: 这是整个动画的核心。transform-style: preserve-3d启用了 3D 模式,transition: transform 0.8s确保当transform属性改变时,动画会持续 0.8 秒。.scene:hover .card: 这是触发翻转的关键,当鼠标悬停在.scene上时,找到其子元素.card并对其应用rotateY(180deg)变换,由于.card有transition属性,这个旋转过程是平滑的。.card-face: 因为两个面都是绝对定位,所以它们会重叠在一起。backface-visibility: hidden是一个非常实用的属性,它确保当一个面旋转到我们看不见的角度时(即背面朝向我们时),它会被隐藏,避免看到内容的镜像,使效果更真实。.card-face-back: 我们通过transform: rotateY(180deg)将背面预先旋转了 180 度,这样,当.card整体旋转 180 度时,正面就转到了背面,而背面(已经旋转了180度的)则转到了正面,实现了无缝的翻转。
高级技巧与变种
点击翻转(而非悬停)
将 hover 伪类改为使用 JavaScript 切换一个 .flipped 类。

(图片来源网络,侵删)
CSS 修改:
/* 移除 .scene:hover .card 的样式 */
.scene .card {
/* ... 其他样式 ... */
}
/* 添加一个新的样式,当卡片有 .flipped 类时进行旋转 */
.card.flipped {
transform: rotateY(180deg);
}
JavaScript 代码:
document.addEventListener('DOMContentLoaded', () => {
const card = document.querySelector('.card');
card.addEventListener('click', () => {
card.classList.toggle('flipped');
});
});
翻转方向(上下翻转)
只需将 rotateY 改为 rotateX 即可。
CSS 修改:
/* 鼠标悬停时,绕X轴旋转 */
.scene:hover .card {
transform: rotateX(180deg);
}
/* 背面也预先绕X轴旋转 */
.card-face-back {
transform: rotateX(180deg);
}
翻转同时移动位置
结合 translateZ 可以让卡片在翻转的同时,向屏幕外或向屏幕内移动,效果更炫酷。
CSS 修改(在翻转的基础上添加位移):
/* 鼠标悬停时,翻转并向屏幕外移动 */ .scene
