CSS 3D 探秘:从布局基础到 3D 立方体

0 阅读5分钟

CSS 3D 探秘:从布局基础到 3D 立方体

通过几个简单的 HTML/CSS 示例,一步步理解现代 CSS 布局与 3D 变换的核心概念。


一、起点:块级与行内——HTML 元素的两大家族

一切 CSS 布局的根基,都建立在浏览器对 HTML 元素的两大分类之上:

类型代表元素特点
块级(block)divpul可以设置宽高;独占一行,会把兄弟元素"挤"到下一行
行内(inline)spana不能设置宽高;不会换行,和兄弟元素和平共处
/* 块级元素天然独占一行 */
div { display: block; }

/* 行内元素随文字流排列 */
span { display: inline; }

打破规则:inline-block

2.html 演示了一个巧妙的中间态——行内块级

.box {
    background-color: red;
    display: inline-block;
    width: 50%;
}

两个 div 并排显示,各自占据 50% 宽度——既不会把兄弟挤下去(行内特性),又能设置宽高(块级特性)。

⚠️ inline-block 的"天坑" :HTML 中标签之间的换行符 \n 会被渲染为一个空格字符。两个 inline-block 元素之间因此会有一个微小的间隙。这是新手最容易踩的坑之一。


二、格式化上下文:布局的"游戏规则"

display 属性不仅仅是改变元素的外在表现,更重要的是它开启了不同的格式化上下文(Formatting Context) ——可以理解为布局的游戏规则:

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

Flex 弹性布局

3.html 展示了 flex 的核心用法:

.box {
    display: flex;        /* 开启弹性格式化上下文 */
    /* flex-direction: row;  /* 默认:主轴水平 */
}
.item {
    flex: 1;              /* 每个子元素等分剩余空间 */
    background-color: red;
    text-align: center;
}

关键认知display: flex 是设置在父容器上的——父与子之间的布局关系由父容器说了算。四个 .item 自动等宽排列,无需手动计算百分比。


三、水平垂直居中:移动端适配的基石

common.css 中展示了最经典、最实用的居中方案:

html, body {
    height: 100vh;          /* vh = viewport-height,视窗高度 */
    display: flex;
    flex-direction: row;    /* 默认值,主轴水平 */
    justify-content: center; /* 主轴(水平)居中 */
    align-items: center;     /* 次轴(垂直)居中 */
}

移动端新单位

  • vh(viewport-height):视窗高度的 1%,100vh = 满屏高度
  • vw(viewport-width):视窗宽度的 1%
  • 相比 100%100vh 直接相对于视窗,不依赖父元素高度

这构成了移动端适配的黄金组合:flex + vh/vw + justify-content/align-items


四、CSS 3D:让平面"立起来"

1.html + common.css 的核心——一个纯 CSS 实现的 3D 旋转立方体

4.1 三维世界的入口:perspective

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

perspective 定义了观察者与 z=0 平面的距离。值越小,透视效果越强烈(物体显得越大、越近);值越大,透视越平缓。可以理解为"相机镜头"的焦距。

4.2 保留 3D 空间:transform-style

.box {
    position: relative;
    transform-style: preserve-3d;  /* 关键:让子元素保留 3D 位置 */
    animation: rotate 5s linear infinite;
}

不加 preserve-3d,所有子元素会被"拍扁"到父元素的 2D 平面——3D 效果荡然无存。

4.3 搭建立方体的六个面

一个立方体有 6 个面,每个面都是 200×200 的正方形,通过 position: absolute 叠加在同一位置,然后用 transform 将它们"推"到空间的对应位置:

.face {
    width: 200px;
    height: 200px;
    position: absolute;      /* 所有面叠在一起 */
    opacity: 0.8;
}

/* 前面:沿 Z 轴向外推 100px(半边长) */
.front  { transform: translateZ(100px); }

/* 后面:沿 Z 轴向内推 100px,再翻转 180° 让文字正向 */
.back   { transform: translateZ(-100px) rotateY(180deg); }

/* 左面:沿 X 轴左移 100px,绕 Y 轴旋转 -90° */
.left   { transform: translateX(-100px) rotateY(-90deg); }

/* 右面:沿 X 轴右移 100px,绕 Y 轴旋转 90° */
.right  { transform: translateX(100px) rotateY(90deg); }

/* 上面:沿 Y 轴上移 100px,绕 X 轴旋转 90° */
.top    { transform: translateY(-100px) rotateX(90deg); }

/* 下面:沿 Y 轴下移 100px,绕 X 轴旋转 -90° */
.bottom { transform: translateY(100px) rotateX(-90deg); }

4.4 让立方体转起来:@keyframes

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

完整的动画链条:

animation: rotate 5s linear infinite
           ↓       ↓   ↓     ↓
         动画名   时长 缓动  循环

4.5 立方体构建原理图

         ┌──────────┐
         │  toptranslateY(-100px) rotateX(90deg)
         └──────────┘
   ┌──────────┬──────────┬──────────┐
   │  left    │  front   │  right   │
   │ -100px X │ +100px Z │ +100px X │
   │ -90° Y   │          │ +90° Y   │
   └──────────┴──────────┴──────────┘
         ┌──────────┐
         │  bottomtranslateY(100px) rotateX(-90deg)
         └──────────┘
         ┌──────────┐
         │  back    │  translateZ(-100px) rotateY(180deg)
         └──────────┘

4.6 GPU 加速:隐藏的福利

CSS 3D 不仅用于 3D 效果。transform: translateZ(0)will-change: transform 会触发 GPU 加速——即使是 2D 界面,有时也会刻意"3D 化"来利用 GPU 渲染,提升动画流畅度。这比传统的 left/top 动画性能好得多,因为 transform 不走重排(reflow),只在合成层上操作。


五、知识全景图

HTML 元素
  ├── 块级 (block) ── 独占一行,可设宽高
  ├── 行内 (inline) ── 不换行,不可设宽高
  └── 行内块级 (inline-block) ── 不换行 + 可设宽高 ⚠️ 空格坑

格式化上下文
  ├── display: flex ── 弹性布局,一维排列
  ├── display: grid ── 网格布局,二维排列
  └── display: inline-block ── 行内块级上下文

定位
  ├── position: relative ── 相对自身原始位置偏移
  └── position: absolute ── 相对最近的定位祖先偏移

CSS 3D
  ├── perspective ── 视距,3D 世界的入口
  ├── transform-style: preserve-3d ── 保留子元素的 3D 空间
  ├── transform: translateZ/rotateY/rotateX ── 空间位移与旋转
  └── @keyframes + animation ── 让 3D 世界动起来

六、动手试试

想亲手体验?只需三个文件:

  1. 新建 1.html,引入 common.css
  2. 复制六个面的 HTML 结构到页面
  3. 在浏览器中打开,看着一个半透明的彩色立方体在你面前缓缓旋转

image.png

你可以尝试调整这些参数来感受变化:

  • 把 perspective: 600px 改成 200px ——透视变强烈
  • 把 animation 的 5s 改成 1s ——旋转加速
  • 给 .box 加上 transform: rotateX(20deg) ——换个观察角度

CSS 3D 的世界,比你想象的更简单,也更有趣 🎲