前言
在 Web 前端开发中,CSS 3D 变换一直是一个既酷炫又容易让人"绕晕"的领域。很多开发者在尝试 3D 效果时,往往因为对文档流、空间坐标系和属性继承理解不透彻而踩坑。今天,我们将结合一个完整的"3D 旋转魔方"实战案例,从最基础的元素排版、Flex 弹性布局,一路剖析到 transform-style: preserve-3d 的核心原理,带你彻底打通 CSS 布局与 3D 变换的任督二脉。
一、 舞台搭建:从文档流到 Flex 布局
在让元素"动"起来之前,我们必须先搞懂它们是如何"站"的。
1. 块级、行内与 inline-block 的坑
在 HTML 中,元素默认分为两类:
- 块级元素(Block) :如
div、ul,独占一行,可以随意设置宽高。 - 行内元素(Inline) :如
span,不独占一行,但无法设置宽高。
如果我们既不想让元素独占一行,又需要设置宽高,可以使用 display: inline-block;(行内块级)。
⚠️ 避坑指南 :inline-block 元素之间默认会存在一个"空格符"的间隙。如果在 HTML 中换行书写,浏览器会将其解析为空格,导致元素无法完美拼接。
css
编辑
css
1/* 行内块级:既能设置宽高,又不会把兄弟挤下去 */
2.box {
3 background-color: #d61717;
4 display: inline-block;
5 width: 50%;
6}
2. Flex 弹性布局:现代布局的利器
为了更优雅地管理子元素,我们通常会开启 Flex 格式化上下文。在 Flex 布局中,子元素默认会沿着主轴排列,并且被父元素"管着":
css
编辑
css
1.box {
2 display: flex;
3 flex-direction: row; /* 默认主轴为水平方向 */
4}
5.item {
6 flex: 1; /* 自动平分剩余空间 */
7 text-align: center;
8}
3. 视口高度与完美居中
为了让我们的 3D 魔方始终在屏幕正中央展示,我们需要让父容器撑满整个屏幕。这里使用了 CSS3 的新单位 100vh(Viewport Height,即视口高度的 100%),这在移动端适配中非常实用。
配合 Flexbox,我们可以极其优雅地实现水平垂直居中:
css
编辑
css
1html, body {
2 height: 100vh;
3 display: flex;
4 justify-content: center; /* 主轴居中 */
5 align-items: center; /* 交叉轴居中 */
6}
二、 3D 核心:构建真实的立体空间
这是整个项目最核心的部分。要让 6 个 2D 的 div 变成一个立体的魔方,需要理解以下三个关键属性:
1. perspective(透视/视距)
没有透视的 3D 都是"假 3D"。perspective 模拟的是"人眼到 3D 舞台的距离"。
- 作用对象 :必须加在父容器上,为子元素创建 3D 观察空间。
- 数值影响 :值越小,透视感越强(物体看起来越大、越近);值越大,立体感越弱。在我们的代码中,
perspective: 600px;提供了一个适中的纵深感。
2. transform-style: preserve-3d(保留 3D 空间)
这是新手最容易误解的属性! 加上它,并不意味着元素会自动变成立体形状。它的作用仅仅是"允许子元素在真实的 3D 空间中散开",而不是被压扁在 2D 平面上。
打个比方:preserve-3d 就像是你撤掉了压在扑克牌上的玻璃板,但如果你不通过 transform 告诉每张牌"各自该朝向哪里",它们依然会叠在一起。
3. transform 与空间坐标系
CSS 3D 采用"右手坐标系":X 轴向右,Y 轴向下,Z 轴指向屏幕外。
-
平移 (
translate) :translateZ(100px)是将元素向屏幕外推 100px。 -
旋转 (
rotate) :rotateY(90deg):绕 Y 轴向右转 90 度(右面)。rotateY(-90deg):绕 Y 轴向左转 90 度(左面)。- 黄金法则:正数代表顺时针,负数代表逆时针(前提是顺着轴的正方向看过去)。
三、 让魔方转起来:animation 的正确姿势
当我们给元素加上 animation: rotate 5s linear infinite; 却发现它纹丝不动时,通常是因为混淆了"动作"与"名称"。
animation 只是"播放键"
animation 属性中的 rotate 仅仅是一个自定义的动画名称(代号) ,它本身并不包含任何旋转动作。真正的动作脚本必须通过 @keyframes 来定义,且名字必须严格对应:
css
编辑
css
1/* 1. 定义动作剧本 */
2@keyframes rotate {
3 0% { transform: rotateX(0deg); }
4 100% { transform: rotateX(360deg); }
5}
6
7/* 2. 调用剧本:名称为 rotate,时长 5s,匀速,无限循环 */
8.box {
9 animation: rotate 5s linear infinite;
10}
四、 完整实战代码
结合上述所有知识点,以下是完整的 3D 魔方实现代码:
html
预览
xml
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>CSS 3D 旋转魔方</title>
7 <style>
8 * { margin: 0; padding: 0; }
9
10 /* 舞台居中 */
11 html, body {
12 height: 100vh;
13 display: flex;
14 justify-content: center;
15 align-items: center;
16 background-color: #111;
17 }
18
19 /* 3D 观察空间 */
20 .box-wrap {
21 width: 200px;
22 height: 200px;
23 perspective: 600px;
24 }
25
26 /* 3D 舞台与动画 */
27 .box {
28 width: 100%;
29 height: 100%;
30 position: relative;
31 transform-style: preserve-3d;
32 animation: rotate 5s linear infinite;
33 }
34
35 /* 动画关键帧 */
36 @keyframes rotate {
37 0% { transform: rotateX(0deg); }
38 100% { transform: rotateX(360deg); }
39 }
40
41 /* 六个面的公共样式 */
42 .face {
43 width: 200px;
44 height: 200px;
45 position: absolute;
46 display: flex;
47 justify-content: center;
48 align-items: center;
49 font-size: 30px;
50 color: #fff;
51 opacity: 0.8;
52 }
53
54 /* 空间定位 */
55 .front { transform: translateZ(100px); background-color: #4299e1; }
56 .back { transform: translateZ(-100px) rotateY(180deg); background-color: #4299e1; }
57 .left { transform: translateX(-100px) rotateY(-90deg); background-color: #2f1271; }
58 .right { transform: translateX(100px) rotateY(90deg); background-color: #8411ab; }
59 .top { transform: translateY(-100px) rotateX(90deg); background-color: #871621; }
60 .bottom { transform: translateY(100px) rotateX(-90deg); background-color: #dfb150; }
61 </style>
62</head>
63<body>
64 <div class="box-wrap">
65 <div class="box">
66 <div class="face front">前</div>
67 <div class="face back">后</div>
68 <div class="face left">左</div>
69 <div class="face right">右</div>
70 <div class="face top">上</div>
71 <div class="face bottom">下</div>
72 </div>
73 </div>
74</body>
75</html>
结语
从基础的 Flex 居中,到理解 preserve-3d 的空间概念,再到掌握 @keyframes 的命名机制,CSS 3D 并没有想象中那么神秘。希望这篇复盘笔记能帮你扫清学习路上的盲区。下次再遇到 3D 效果,不妨试着在脑海中建立那个三维坐标系,一切都会迎刃而解!