3、CSS 3D变换:perspective、rotateX/Y/Z、scale3d 与 3D 空间构建
CSS 3D 变换,说白了就是让网页元素「立起来」。很多同学觉得它难,其实核心就三样东西:透视、旋转、缩放。我刚开始接触时也绕了不少弯路,今天咱们把这几个点彻底讲透。
3.1 透视(perspective):3D 空间的灵魂
没有透视,就没有 3D 效果。你想想看,为什么近大远小?因为我们的眼睛有透视。CSS 里也一样,你得告诉浏览器「从多远的地方看这个元素」。
核心概念:perspective 的值越小,透视效果越强烈(就像贴着脸看);值越大,效果越平缓(就像站远了看)。
有两种写法,我建议你区分清楚:
| 写法 | 作用范围 | 适用场景 |
|---|---|---|
perspective: 800px; 写在父容器 |
所有子元素共享同一个透视点 | 卡片组、轮播图、3D 画廊 |
transform: perspective(800px) rotateY(45deg); |
只影响当前元素 | 单个元素的独立 3D 变换 |
我的习惯:如果多个元素需要保持空间一致性(比如一个立方体的六个面),一定用父容器透视。否则每个元素各自为政,看起来会「穿帮」。
3.2 旋转(rotateX/Y/Z):让元素转起来
旋转是 3D 变换里最直观的操作。三个轴对应三个方向:
- rotateX(angle) — 绕 X 轴旋转,像翻书页
- rotateY(angle) — 绕 Y 轴旋转,像转门
- rotateZ(angle) — 绕 Z 轴旋转,像转盘子(其实就是 2D 旋转)
我在项目中遇到过一个问题:旋转 90 度后元素背面朝前,内容就消失了。这是因为浏览器默认不渲染背面。解决方案很简单:
/* 让背面可见 */
.card {
backface-visibility: visible;
}
/* 或者直接隐藏背面(更常用) */
.card {
backface-visibility: hidden;
}
我曾经踩过的坑:旋转角度用 deg 还是 turn?1turn = 360deg。但 Safari 对 turn 的支持有 bug,所以我统一用 deg,省心。
3.3 scale3d:不只是放大缩小
scale3d(sx, sy, sz) 可以分别控制三个维度的缩放。但注意:Z 轴缩放需要元素有厚度,否则看不出效果。
举个例子,一个卡片 hover 时放大:
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: scale3d(1.1, 1.1, 1.1);
}
嗯,这里要注意:scale3d 的 Z 轴缩放,配合 translateZ 才能做出「拉近拉远」的立体感。单独用 Z 轴缩放,在普通 div 上基本没反应。
3.4 3D 空间构建:从零搭一个立方体
理论说再多,不如动手搭一个。咱们用纯 CSS 做一个旋转立方体,把上面所有知识点串起来。
先看 HTML 结构:
<div class="cube-container">
<div class="cube">
<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>
CSS 核心代码:
.cube-container {
perspective: 800px;
width: 200px;
height: 200px;
margin: 100px auto;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation: spin 6s infinite linear;
}
.face {
position: absolute;
width: 200px;
height: 200px;
background: rgba(52, 152, 219, 0.7);
border: 2px solid #2980b9;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: #fff;
}
.front { transform: translateZ(100px); }
.back { transform: rotateY(180deg) translateZ(100px); }
.left { transform: rotateY(-90deg) translateZ(100px); }
.right { transform: rotateY(90deg) translateZ(100px); }
.top { transform: rotateX(90deg) translateZ(100px); }
.bottom { transform: rotateX(-90deg) translateZ(100px); }
@keyframes spin {
from { transform: rotateY(0deg); }
to { transform: rotateY(360deg); }
}
关键点:transform-style: preserve-3d 必须加在父容器上,否则子元素的 3D 变换会被压平。我见过太多人漏掉这一行,然后跑来问我「为什么我的立方体是平的?」
3.5 知识体系总览
下面这张图把本章的核心逻辑串起来了,你可以对照着理解:
3.6 常见问题与避坑
最后分享几个我实际项目中踩过的坑:
问题一:3D 变换后文字模糊
原因:浏览器在 3D 变换时启用了硬件加速,但某些 GPU 对文字渲染有瑕疵。解决方案:给文字加 translateZ(0) 强制开启独立图层。
问题二:动画卡顿
原因:同时变换太多属性。我建议只变换 transform 和 opacity,这两个属性浏览器会走合成器线程,不触发重排。
问题三:子元素 3D 效果被父容器裁剪
检查父容器有没有 overflow: hidden。如果有,3D 变换超出部分会被裁掉。要么去掉 overflow,要么调整透视距离让元素不超出。
嗯,CSS 3D 变换其实没那么玄乎。记住三个核心:透视给空间感,旋转定方向,缩放调大小。再加上 preserve-3d 这个开关,你就能搭出各种 3D 效果了。多动手试试,比看十遍教程都管用。