# CSS3核心特性-第9章-9.2-3D变换与透视
## 学习目标
- 理解3D变换的核心概念(透视、3D空间、变换原点)
- 掌握`perspective`属性的语法与取值规则
- 实现基础3D变换效果(旋转、平移、缩放)
- 掌握`transform-style: preserve-3d`的应用场景
- 能够开发简单的3D交互效果(如卡片翻转、立方体展示)
## 概念讲解
3D变换是CSS3在2D变换基础上扩展的空间变换能力,通过模拟三维空间坐标系实现元素的立体效果。与2D变换相比,3D变换增加了**Z轴**维度,使元素能够在三维空间中进行旋转、平移和缩放。
### 核心术语
- **三维坐标系**:以元素左上角为原点,X轴(水平方向)、Y轴(垂直方向)、Z轴(垂直屏幕方向,正值向外)
- **透视(Perspective)**:模拟人眼观察物体的"近大远小"效果,值越小透视感越强(默认无透视)
- **变换样式(Transform Style)**:控制子元素是否继承3D空间(`preserve-3d`开启3D空间,`flat`默认平面)
- **变换原点(Transform Origin)**:3D变换的基准点(默认元素中心,可通过`transform-origin`调整)
### 3D与2D变换的区别
| **特性** | **2D变换** | **3D变换** |
| ---------- | ------------------------- | ---------------------------- |
| 坐标系 | X轴、Y轴 | X轴、Y轴、Z轴 |
| 透视效果 | 无 | 需设置`perspective`属性 |
| 子元素空间 | 平面堆叠 | 可形成3D空间层次 |
| 典型属性 | `translate()`、`rotate()` | `translate3d()`、`rotateX()` |
## 语法参考
### 1. 透视属性(`perspective`)
定义3D空间的透视距离,决定元素的立体感强度。可应用于父容器(影响所有子元素)或自身(仅影响自身)。
| **语法** | **取值** | **描述** |
| ------------------------ | ------------------ | ---------------------- |
| `perspective: none` | 默认值,无透视效果 | 元素以2D方式渲染 |
| `perspective: 数值+单位` | 如`500px`、`800px` | 数值越小,透视效果越强 |
**示例**:
```css
/* 父容器设置透视,影响所有子元素 */
.container {
perspective: 800px; /* 透视距离800px */
}
/* 子元素应用3D变换 */
.box {
transform: rotateY(45deg); /* 沿Y轴旋转45度 */
}
```
### 2. 3D变换属性(`transform`)
在2D变换基础上新增3D专属函数,支持Z轴变换:
| **函数** | **作用** | **示例** |
| ---------------------- | ------------------------------------ | ---------------------------------------------- |
| `translate3d(x, y, z)` | 3D平移(Z轴正值向外) | `translate3d(50px, 20px, 100px)` |
| `rotateX(angle)` | 沿X轴旋转(上下翻转) | `rotateX(45deg)` |
| `rotateY(angle)` | 沿Y轴旋转(左右翻转) | `rotateY(45deg)` |
| `rotateZ(angle)` | 沿Z轴旋转(平面旋转,同2D `rotate`) | `rotateZ(30deg)` |
| `scale3d(x, y, z)` | 3D缩放(Z轴缩放影响厚度感) | `scale3d(1.2, 1.2, 1.5)` |
| `perspective(n)` | 单个元素设置透视(仅影响自身) | `transform: perspective(500px) rotateY(30deg)` |
### 3. 3D空间样式(`transform-style`)
控制子元素是否处于3D空间中,必须设置在父元素上。
| **取值** | **效果** |
| ------------- | -------------------------------- |
| `flat` | 默认值,子元素在平面上渲染 |
| `preserve-3d` | 子元素保持3D空间关系,可相互遮挡 |
**示例**:
```css
.parent {
transform-style: preserve-3d; /* 开启3D空间 */
transform: rotateX(30deg);
}
.child {
transform: translateZ(50px); /* 子元素沿Z轴平移,形成层次感 */
}
```
### 4. 背面可见性(`backface-visibility`)
控制元素旋转后背面是否可见(常用于卡片翻转效果)。
| **取值** | **效果** |
| --------- | ------------------ |
| `visible` | 默认值,背面可见 |
| `hidden` | 背面不可见(透明) |
**示例**:
```css
.card {
backface-visibility: hidden; /* 旋转后背面隐藏 */
transform-style: preserve-3d;
}
.card:hover {
transform: rotateY(180deg); /* 翻转后显示正面 */
}
```
## 实战示例
### 示例1:基础3D旋转效果
实现沿Y轴旋转的立方体效果,包含透视设置和3D空间开启。
```html
```
#### 效果说明:
- 父容器`.perspective-container`设置`perspective: 1000px`提供透视环境
- `.cube`通过`transform-style: preserve-3d`开启3D空间,使6个子元素(面)处于同一3D坐标系
- 每个面通过`translateZ/X/Y`定位到正方体的6个面,结合旋转形成立方体结构
- 悬停时沿Y轴旋转360度+45度,展示3D空间效果
### 示例2:3D卡片翻转效果
实现鼠标悬停时卡片沿Y轴翻转,显示背面内容。
```html
```
#### 关键技术点:
- `backface-visibility: hidden`确保卡片翻转时只显示当前面
- 背面初始状态`rotateY(180deg)`,悬停时父元素触发`rotateY(180deg)`实现翻转
- `transform-style: preserve-3d`保证正反面在同一3D空间,避免平面重叠
## 注意事项
### 1. 浏览器兼容性
- **IE支持**:IE10+部分支持3D变换,但不支持`preserve-3d`,需使用`transform: matrix3d()`手动计算矩阵
- **移动端**:iOS Safari 9.1+、Android Chrome 43+完全支持,低版本可能存在透视异常
- 前缀
:部分老浏览器需添加
```
-webkit-
```
前缀(如Safari 8-、Android Browser 4.4-):
```css
.element {
-webkit-perspective: 800px;
perspective: 800px;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
```
### 2. 性能优化
- **避免过度使用**:3D变换(尤其是动画)会触发GPU加速,过多元素同时动画可能导致性能问题
- **简化3D场景**:复杂3D场景(如多个嵌套3D元素)建议使用`will-change: transform`提示浏览器优化
- **控制透视距离**:`perspective`值不宜过小( 答案:B
2. 要实现元素沿X轴旋转90度,同时具有透视效果,正确的CSS是?
```css
/* A */
.box {
transform: rotateX(90deg);
}
/* B */
.container {
perspective: 600px;
}
.box {
transform: rotateX(90deg);
}
/* C */
.box {
perspective: 600px;
transform: rotate(90deg);
}
/* D */
.container {
transform-style: preserve-3d;
}
.box {
transform: rotateX(90deg);
}
```
> 答案:B(需在父容器设置`perspective`提供透视环境)
3. 3D变换中,`translateZ(100px)`和`translateZ(-100px)`的视觉效果区别是?
> 答案:`translateZ(100px)`使元素沿Z轴正向移动(靠近观察者,视觉变大);`translateZ(-100px)`沿Z轴负向移动(远离观察者,视觉变小)
4. 实现卡片翻转效果时,为什么需要设置`backface-visibility: hidden`?
> 答案:防止卡片翻转过程中正面和背面同时可见(重叠显示),设置后旋转超过90度时背面自动隐藏,提升视觉效果
## 扩展阅读
- [MDN 3D变换指南](https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_transforms/Using_CSS_transforms#3d_变换)
- [CSS Tricks: perspective属性详解](https://css-tricks.com/almanac/properties/p/perspective/)
- [3D变换性能优化实践](https://developers.google.com/web/fundamentals/performance/rendering/stick-to-compositor-only-properties-and-manage-layer-count)