核心原理

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

html5 css3 实现网页3d翻转
(图片来源网络,侵删)
  1. perspective (透视)

    • 作用:定义了观察者与 3D 空间之间的距离,没有透视,3D 变换看起来就是扁平的 2D 缩放。perspective 的值越小,透视效果越强烈,物体变形越明显。
    • 应用位置:通常设置在父容器(.scene)上,它为整个 3D 场景提供了观察的视点。
  2. transform-style: preserve-3d

    • 作用:这是一个至关重要的属性,它告诉浏览器,其子元素应该在真正的 3D 空间中进行渲染,而不是被扁平化,如果缺少这个属性,你的翻转卡片将只会看起来像是在原地缩放。
    • 应用位置:设置在需要进行 3D 变换的元素的直接父容器(.card)上。
  3. transform (变换)

    • 作用:这是执行实际变换的属性,对于翻转效果,我们主要使用:
      • rotateY(): 绕 Y 轴(垂直轴)旋转,实现左右翻转。
      • rotateX(): 绕 X 轴(水平轴)旋转,实现上下翻转。
    • 应用位置:设置在需要翻转的子元素(.card-front, .card-back)上,我们将其中一个面(例如背面)旋转 180 度,使其一开始就“背对着”我们。
  4. transition (过渡)

    html5 css3 实现网页3d翻转
    (图片来源网络,侵删)
    • 作用:让 CSS 属性的变化(如 transform 的变化)有一个平滑的动画效果,而不是瞬间完成。
    • 应用位置:通常设置在需要进行翻转的元素(.card)上,这样当它应用 transform 时,动画就会生效。

分步实现:一个 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-3dtransition,并作为翻转的载体。
  • .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;
}

代码解析

  1. .scene: 设置了固定的宽高和 perspective: 1000px,定义了我们观察这个 3D 场景的窗口。
  2. .card: 这是整个动画的核心。transform-style: preserve-3d 启用了 3D 模式,transition: transform 0.8s 确保当 transform 属性改变时,动画会持续 0.8 秒。
  3. .scene:hover .card: 这是触发翻转的关键,当鼠标悬停在 .scene 上时,找到其子元素 .card 并对其应用 rotateY(180deg) 变换,由于 .cardtransition 属性,这个旋转过程是平滑的。
  4. .card-face: 因为两个面都是绝对定位,所以它们会重叠在一起。backface-visibility: hidden 是一个非常实用的属性,它确保当一个面旋转到我们看不见的角度时(即背面朝向我们时),它会被隐藏,避免看到内容的镜像,使效果更真实。
  5. .card-face-back: 我们通过 transform: rotateY(180deg) 将背面预先旋转了 180 度,这样,当 .card 整体旋转 180 度时,正面就转到了背面,而背面(已经旋转了180度的)则转到了正面,实现了无缝的翻转。

高级技巧与变种

点击翻转(而非悬停)

hover 伪类改为使用 JavaScript 切换一个 .flipped 类。

html5 css3 实现网页3d翻转
(图片来源网络,侵删)

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