纯 CSS 实现 3D 旋转立方体!不需要 Three.js 也能玩转 CSS 3D

5 阅读8分钟

🎲 纯 CSS 实现 3D 旋转立方体!不需要 Three.js 也能玩转 CSS 3D

本文基于实际代码示例,从零讲解 CSS 3D 变换的核心原理,带你用纯 CSS + HTML 搭建一个会旋转的 3D 立方体。不需要任何第三方库,不需要 Canvas,只需要你熟悉的 CSS。

前言

提到 Web 3D,很多同学第一反应就是 Three.js、WebGL 这些"重量级"方案。但你知道吗?CSS3 本身就内置了强大的 3D 变换能力。而且,哪怕你做的是 2D 页面,手动开启 3D 模式还能带来 GPU 加速 的性能提升。

今天我们就来聊聊 CSS 3D 的那些事儿,从基础的布局知识讲起,一步步实现一个纯 CSS 的 3D 旋转立方体。

一、CSS 3D vs Canvas:什么时候用哪个?

在开始之前,先理清一个概念:

特性CSS 3DCanvas
实现方式CSS 属性驱动JavaScript API 绘制
性能GPU 加速,适合简单变换适合复杂图形和像素级操作
适用场景UI 动画、卡片翻转、简单 3D 效果游戏、数据可视化、复杂 3D 场景
学习成本低,CSS 开发者友好中高,需要掌握 Canvas API

结论:如果你只是需要做一些 UI 级别的 3D 效果(翻牌、旋转、透视),CSS 3D 完全够用,而且性能更好。

二、前置知识:布局基础

在进入 3D 之前,我们先快速回顾几个 CSS 布局的核心概念。这些是后面理解 3D 变换的基础。

2.1 行内元素 vs 块级元素

HTML 元素本质上分两类:

  • 块级元素divulp 等):独占一行,可以设置宽高
  • 行内元素spana 等):不会把兄弟挤下去,不能直接设置宽高
/* 块级元素:独占一行,可设宽高 */
div {
  width: 200px;
  height: 200px;
}

/* 行内元素:宽高设置无效 */
span {
  width: 200px;  /* ❌ 无效 */
  height: 200px; /* ❌ 无效 */
}

2.2 display 属性的三阶进化

CSS 的 display 属性经历了三个阶段的进化:

浏览器默认(block/inline)
    ↓
手动切换(inline/block)
    ↓
格式化上下文(flex / inline-block / grid

其中 inline-block 是个"两面派":

.box {
  display: inline-block;
  /* ✅ 不会把兄弟挤下去(行内特性) */
  /* ✅ 可以设置宽高(块级特性) */
}

⚠️ 踩坑提醒inline-block 有一个经典天坑——元素之间的空白符(\n\r、空格)会被渲染成一定的间距。解决方案:父元素 font-size: 0 或者把 HTML 标签写在一行。

2.3 Flex 弹性布局:移动端的首选

.container {
  display: flex;
  justify-content: center;  /* 主轴居中 */
  align-items: center;      /* 次轴居中 */
}

Flex 布局开启了弹性格式化上下文,子元素们默认会沿主轴排列,并且受父元素控制。这是目前移动端最常用的布局方式。

2.4 水平垂直居中的终极方案

html, body {
  height: 100vh;  /* 视窗高度的 100% */
  display: flex;
  justify-content: center;
  align-items: center;
}

这里用到了 vh(viewport-height)和 vw(viewport-width)这两个 CSS3 新单位。100vh 表示视窗高度的 100 份,等比例适配各种屏幕尺寸,是移动端适配的利器。

三、CSS 3D 的核心概念

好了,铺垫完毕,正式进入 3D 世界!

3.1 两大核心属性

CSS 3D 变换的灵魂只有两个属性:

/* 1. 视距(透视距离)—— 决定 3D 效果的强烈程度 */
perspective: 600px;

/* 2. 3D 空间保持 —— 让子元素在 3D 空间中渲染 */
transform-style: preserve-3d;

perspective 可以理解为"你的眼睛离物体有多远":

  • 值越小,透视效果越强烈(像鱼眼镜头)
  • 值越大,透视效果越微弱(像长焦镜头)
  • 一般设置在 500px ~ 1000px 之间比较自然

transform-style: preserve-3d 告诉浏览器:"我的子元素要在这个 3D 空间里自由变换,不要把它们拍扁成 2D"。

3.2 transform 的 3D 变换函数

CSS 的 transform 属性提供了丰富的 3D 变换函数:

/* 沿 X 轴旋转(上下翻转) */
transform: rotateX(45deg);

/* 沿 Y 轴旋转(左右翻转) */
transform: rotateY(45deg);

/* 沿 Z 轴旋转(平面旋转) */
transform: rotateZ(45deg);

/* 沿 Z 轴平移(前后移动) */
transform: translateZ(100px);

/* 组合变换 */
transform: translateX(100px) rotateY(90deg);

💡 关键理解translateZ 就是让元素"前进"或"后退"。正值向前(靠近你),负值向后(远离你)。这是构建 3D 立方体的核心操作。

四、实战:纯 CSS 搭建 3D 旋转立方体

理解了上面的理论,接下来我们用纯 CSS + HTML 搭建一个会自动旋转的 3D 立方体。

4.1 HTML 结构

<div class="box-wrap">
  <div class="box">
    <div class="face front"></div>
    <div class="face back"></div>
    <div class="face left"></div>
    <div class="face right"></div>
    <div class="face top"></div>
    <div class="face bottom"></div>
  </div>
</div>

结构非常直观:

  • box-wrap:外层容器,设置 perspective(视距)
  • box:旋转层,承载动画
  • face:六个面,各自通过 transform 定位到正确位置

4.2 全局样式与居中

* {
  margin: 0;
  padding: 0;
}

html, body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

经典的 Flex 居中方案,让立方体在页面正中央展示。

4.3 3D 容器设置

.box-wrap {
  width: 200px;
  height: 200px;
  /* 3D 核心:视距 */
  perspective: 600px;
}

.box {
  width: 100%;
  height: 100%;
  position: relative;
  /* 3D 核心:保持 3D 空间 */
  transform-style: preserve-3d;
  /* 自定义旋转动画 */
  animation: rotate 5s linear infinite;
}

这里 perspective 设置在父容器上,transform-style 设置在旋转元素上。这个组合是 CSS 3D 的"黄金搭档"。

4.4 六个面的定位

这是整个立方体最关键的部分。每个面都需要:

  1. 绝对定位(position: absolute
  2. 通过 translateZ 向前/后移动到正确位置
  3. 通过 rotateX/Y 旋转到正确朝向
.face {
  width: 200px;
  height: 200px;
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 30px;
  color: #fff;
  opacity: 0.8;
}

/* 前面:向前推进 100px,旋转 180° 让文字朝外 */
.front {
  background: #4299e1;
  transform: translateZ(100px) rotateY(180deg);
}

/* 后面:向后退 100px */
.back {
  background: #f5656f;
  transform: translateZ(-100px);
}

/* 左面:向左移 100px,逆时针旋转 90° */
.left {
  background: #48bb78;
  transform: translateX(-100px) rotateY(-90deg);
}

/* 右面:向右移 100px,顺时针旋转 90° */
.right {
  background: #48bb78;
  transform: translateX(100px) rotateY(90deg);
}

/* 上面:向上移 100px,逆时针旋转 90° */
.top {
  background: #9f7aea;
  transform: translateY(-100px) rotateX(90deg);
}

/* 下面:向下移 100px,顺时针旋转 90° */
.bottom {
  background: #ecc94b;
  transform: translateY(100px) rotateX(-90deg);
}

🎯 记忆口诀:前后用 translateZ,左右用 translateX,上下用 translateY。移动距离 = 立方体边长的一半(这里是 100px)。

4.5 旋转动画

@keyframes rotate {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(360deg);
  }
}

animation: rotate 5s linear infinite 的含义:

参数含义
动画名rotate对应 @keyframes rotate
持续时间5s一次动画 5 秒
速度曲线linear匀速旋转
重复次数infinite无限循环

五、进阶思考

5.1 为什么要做 3D 化?

哪怕你做的是 2D 界面,有时候也会手动开启 3D 变换:

/* 强制开启 GPU 加速 */
.animated-element {
  transform: translateZ(0);
  /* 或者 */
  will-change: transform;
}

这是因为浏览器在检测到 3D 变换时,会自动将元素提升到独立的合成层(Compositing Layer),由 GPU 直接处理,避免了 CPU 的重排和重绘,动画更流畅。

5.2 性能优化建议

  1. perspective 放在父元素上,而不是 transform 属性里。单独设置的 perspective 性能更好
  2. 避免频繁触发重排:只使用 transformopacity 做动画,这两个属性不会触发重排
  3. 合理使用 will-change:提前告诉浏览器哪些属性要变化,让它提前准备
  4. 控制合成层数量:每个合成层都会占用显存,不要滥用

5.3 更多玩法

掌握了这些基础,你可以尝试:

  • 卡片翻转效果:鼠标 hover 翻转显示背面内容
  • 3D 轮播图:多张图片围成一圈旋转
  • 3D 导航菜单:立体展开的菜单效果
  • 书本翻页:模拟真实翻书的动画

六、完整代码

HTML(index.html)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS 3D 立方体</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="box-wrap">
    <div class="box">
      <div class="face front"></div>
      <div class="face back"></div>
      <div class="face left"></div>
      <div class="face right"></div>
      <div class="face top"></div>
      <div class="face bottom"></div>
    </div>
  </div>
</body>
</html>

CSS(style.css)

* {
  margin: 0;
  padding: 0;
}

html, body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.box-wrap {
  width: 200px;
  height: 200px;
  perspective: 600px;
}

.box {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  animation: rotate 5s linear infinite;
}

@keyframes rotate {
  0% { transform: rotateY(0deg); }
  100% { transform: rotateY(360deg); }
}

.face {
  width: 200px;
  height: 200px;
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 30px;
  color: #fff;
  opacity: 0.8;
}

.front  { background: #4299e1; transform: translateZ(100px) rotateY(180deg); }
.back   { background: #f5656f; transform: translateZ(-100px); }
.left   { background: #48bb78; transform: translateX(-100px) rotateY(-90deg); }
.right  { background: #48bb78; transform: translateX(100px) rotateY(90deg); }
.top    { background: #9f7aea; transform: translateY(-100px) rotateX(90deg); }
.bottom { background: #ecc94b; transform: translateY(100px) rotateX(-90deg); }

总结

CSS 3D 变换并不是什么黑魔法,核心就两个属性:perspective(视距)和 transform-style: preserve-3d(3D 空间)。配合 translateX/Y/ZrotateX/Y/Z,你就能在浏览器里构建出各种 3D 效果。

对于日常开发中的 UI 动画需求,CSS 3D 完全够用,而且比引入 Three.js 这样的重量级库要轻量得多。下次遇到卡片翻转、立体轮播这类需求,不妨先试试纯 CSS 方案。


如果这篇文章对你有帮助,点个赞 👍 收藏 ⭐ 支持一下吧!有问题欢迎在评论区讨论~