正在加载...

CSS 3D 变换

Optional Advanced 刚调过指针、插入符和原生控件外观。这最后一课可选课是另一套工具:3D 变换。给卡片一个消失点,让它在深度里倾斜。你不是在重写二维 translate / scale 悬停课,也不是在选光标或拉伸手柄。

直接回答

CSS 3D 变换用的仍是二维里那条 transform,再加上深度。把 perspective 放在父级上,让子元素共享一个消失点(perspective-origin 移动该点)。rotateX 和 rotateY 绕水平轴、竖直轴倾斜;rotateZ 就是你熟悉的平面旋转。translateZ 靠近或远离观察者。transform-style: preserve-3d 让子元素留在同一场景里,而不是被压平。backface-visibility: hidden 在面转过去时藏起它——适合双面卡片。布局占位仍和二维一样。角度要小。尊重 prefers-reduced-motion。

为什么这不是二维运动,也不是界面铬层

二维变换课教的是平面运动:translate、rotate、scale、skew,以及作铰链的 transform-origin。那些仍然有效。三维加上类似相机的 perspective 和额外轴。用户界面 CSS 是交互铬层(cursor、resize、caret-color、appearance)。旋转过的卡片不需要撒谎的小手,文本域手柄也不是消失点。只要抬高 2px,就留在二维。

Perspective —— 把相机放在父级

perspective 是长度:数值越小越近、越夸张;越大越平。放在舞台上,而不是每一张脸上,好让兄弟共享一个消失点。

Perspective on the parent

css
.stage {
perspective: 800px;
perspective-origin: 50% 40%;
}

.card-3d {
transform: rotateY(18deg);
transform-origin: center;
}

也可以在一个元素上写 transform: perspective(800px) rotateY(18deg)。那台相机只属于那个盒子。立方体或一排瓷砖,父级 perspective 更克制。perspective-origin 是 transform-origin 的消失点表亲——它不替代旋转面的支点。

轴 —— rotateX、rotateY、rotateZ

想一本书。rotateY 把封面左右打开。rotateX 朝你或远离你点头。rotateZ 在纸面上转——就是二维的 rotate()。

rotateX rotateY rotateZ

css
.tile-y {
transform: rotateY(-22deg);
}

.tile-x {
transform: rotateX(12deg);
}

.tile-z {
transform: rotateZ(8deg);
}

需要时再和二维函数串起来:rotateY(16deg) translateZ(24px)。顺序有意义——后面的函数在前面的局部空间里执行。和二维课一样,一条 transform 列表就够。整篇文章上 rotateX(80deg) 是嘉年华,不是界面。

translateZ —— 距离,不是布局推挤

有 perspective 时,正的 translateZ 常常朝向观察者。文档里的邻居不会让位;只有绘制在动,和二维 translate 一样。

translateZ in a 3D scene

css
.stage {
perspective: 900px;
}

.pop-face {
transform: translateZ(40px) rotateY(-8deg);
}

.back-face {
transform: translateZ(-28px);
}

用 translateZ 分开场景里的面,不要拿它冒充 margin 或日常 z-index。z-index 仍在二维布局里给重叠盒子排序;三维距离是另一颗旋钮。若任务是「把标签抬高 2px」,二维课的 translateY 就够。

preserve-3d —— 保住场景,不要压平

默认情况下,父级会把变换过的子元素压平(transform-style: flat)。三维关系就没了。立方体、叠着的封面或双面卡,要在旋转的包裹层上设 preserve-3d。

preserve-3d on the scene

css
.scene {
perspective: 700px;
}

.rig {
transform-style: preserve-3d;
transition: transform 0.45s ease;
}

.rig.is-flipped {
transform: rotateY(180deg);
}

.face {
position: absolute;
inset: 0;
backface-visibility: hidden;
}

每个该保留深度的祖先都需要 preserve-3d——忘了一个 flat 父级,立方体就变成海报。常见分法:外层舞台放 perspective,内层支架放 preserve-3d:相机在外,关节在内。

backface-visibility —— 藏起背面

面转过 90° 时,否则会看到镜像。backface-visibility: hidden 去掉那一面。配对两面:正面 rotateY(0),背面 rotateY(180deg),都在同一支架上 position: absolute。

Card flip with backface-visibility

css
.card-rig {
position: relative;
transform-style: preserve-3d;
}

.card-front,
.card-back {
position: absolute;
inset: 0;
backface-visibility: hidden;
}

.card-back {
transform: rotateY(180deg);
}

不藏背面,就会透出正面的鬼魂。这不是 user-select: none,也不是 appearance: none。你在三维里藏绘制的面,不是给复选框剥皮。

三维 vs 二维变换 vs 界面铬层

📊 3D vs 2D transform vs UI chrome

Tool Job Poor fit
perspective + rotateX / rotateY / translateZ 深度场景:倾斜、距离、共享消失点 日常 2px 悬停抬起;指针形状
2D translate / rotate / scale / skew 平面运动;origin 铰链 没有 preserve-3d 就堆立方体
transform-style / backface-visibility 嵌套三维面;藏起反面 插入符颜色;文本域 resize
UI(cursor、resize、appearance…) 控件上的交互铬层 消失点;翻卡片

Optional Advanced 已经给控件上过样式。Effects & Motion 已经教过二维映射。这一课是 transform 上的深度层。标题因为有 rotateY 就加 cursor: pointer,不会让它变成三维。登录表上的 perspective 也替不了备注框的 resize。

克制的习惯

界面卡片把 perspective 放在几百像素这一档(600px–1200px 合理)。不要在 body 上写 perspective: 40px。用短 transition 把 :hover 或类接到 transform 上——和二维一样。用 prefers-reduced-motion: reduce 关掉花活(none 或很小的二维轻推)。键盘焦点仍需要看得见的环;翻转不是焦点样式。

Modest 3D hover not a 2D lift

css
.preview {
perspective: 1000px;
}

.preview .plate {
transition: transform 0.3s ease;
}

.preview:hover .plate {
transform: rotateY(-10deg) rotateX(4deg);
}

@media (prefers-reduced-motion: reduce) {
.preview .plate,
.preview:hover .plate {
transition: none;
transform: none;
}
}

这次悬停是倾斜,不是二维标签抬起 translateY(-0.15rem),也不是字段上的 resize: vertical。减少动效的用户想要静止卡片,就听他们的。

自己试试

  1. 用 .stage { perspective: 800px; } 包住卡片,子元素设 rotateY(20deg) —— 再把 perspective 挪到子元素的 transform 上,比较相邻瓷砖。
  2. 做双面卡:支架上 preserve-3d,两面都 backface-visibility: hidden,背面 rotateY(180deg)。
  3. 正面加 translateZ(32px);确认布局邻居不挪位。
  4. 用类 + transition: transform 翻转 —— 再用 prefers-reduced-motion 压平。
  5. 不要用 cursor、resize 或纯二维 translateY 悬停来交差。

常见错误

  • 在 body 上写 perspective: 50px,整页扭曲
  • 包裹层忘了 preserve-3d,却奇怪立方体是扁的
  • 把二维标签抬起(translateY)当成三维课
  • 用界面铬层(cursor、resize、appearance)冒充深度
  • 把 backface-visibility 写在舞台上而不是面上
  • 大 rotateY 翻转时忽略 prefers-reduced-motion
  • 指望三维像 margin 一样改文档流

小结

  • 3D 变换给 transform 加深度:perspective、rotateX / rotateY、translateZ
  • perspective 放在父级场景;用 preserve-3d 让嵌套面留在该空间
  • backface-visibility: hidden 藏起转过去的面
  • 既不是二维悬停抬起课,也不是用户界面铬层
  • 角度要小;尊重减少动效
  • 本课是本课程最后一节 CSS —— Optional Advanced 到此结束;地图上没有下一个 CSS slug

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
7
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部