使用 CSS 变换
通过修改坐标空间,CSS 变换改变了受影响内容的形状和位置,而不会干扰正常的文档流。本指南介绍了如何使用变换。
CSS 变换通过一组 CSS 属性实现,这些属性允许你将仿射线性变换应用于 HTML 元素。这些变换包括平面和 3D 空间中的旋转、倾斜、缩放和平移。
CSS 变换属性
主要使用两个属性来定义 CSS 变换:transform(或单独的 translate、rotate 和 scale 属性)和 transform-origin。
transform-origin-
指定原点的位置。默认情况下,它位于元素的中心,并且可以移动。它被一些变换使用,如旋转、缩放或倾斜,这些变换需要一个特定的点作为参数。
transform-
指定要应用于元素的变换。它是一个以空格分隔的变换列表,这些变换按照组合操作的要求一个接一个地应用。复合变换实际上是从右到左应用的。
示例
这是 MDN 标志的未更改图像

旋转
这是 MDN 标志,从其左下角旋转 90 度。
<img src="logo.png" alt="MDN Logo" />
img {
rotate: 90deg;
transform-origin: bottom left;
}
倾斜和平移
这是 MDN 标志,倾斜 10 度并在 X 轴上平移 150 像素。
<img src="logo.png" alt="MDN logo" />
img {
transform: skewX(10deg) translateX(150px);
transform-origin: bottom left;
}
3D 特定 CSS 属性
在 3D 空间中执行 CSS 变换有点复杂。你必须首先通过赋予它透视来配置 3D 空间,然后你必须配置 2D 元素在该空间中的行为方式。
透视
要设置的第一个元素是 perspective。透视给我们带来了 3D 印象。元素离观察者越远,它们就越小。
设置透视
此示例显示了一个立方体,透视设置在不同的位置。立方体收缩的速度由 perspective 属性定义。其值越小,透视越深。
HTML
下面的 HTML 创建了四个相同的盒子的副本,透视设置在不同的值。
<table>
<tbody>
<tr>
<th><code>perspective: 250px;</code></th>
<th><code>perspective: 350px;</code></th>
</tr>
<tr>
<td>
<div class="container">
<div class="cube perspective-250">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
<td>
<div class="container">
<div class="cube perspective-350">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
</tr>
<tr>
<th><code>perspective: 500px;</code></th>
<th><code>perspective: 650px;</code></th>
</tr>
<tr>
<td>
<div class="container">
<div class="cube perspective-500">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
<td>
<div class="container">
<div class="cube perspective-650">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
CSS
CSS 建立了一些类,可以用于将透视设置为不同的距离。它还包括用于容器盒和立方体本身以及其每个面的类。
/* Shorthand classes for different perspective values */
.perspective-250 {
perspective: 250px;
}
.perspective-350 {
perspective: 350px;
}
.perspective-500 {
perspective: 500px;
}
.perspective-650 {
perspective: 650px;
}
/* Define the container div, the cube div, and a generic face */
.container {
width: 200px;
height: 200px;
margin: 75px 0 0 75px;
border: none;
}
.cube {
width: 100%;
height: 100%;
perspective-origin: 150% 150%;
transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
width: 100px;
height: 100px;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
backface-visibility: visible;
}
/* Define each face based on direction */
.front {
background: rgb(0 0 0 / 30%);
transform: translateZ(50px);
}
.back {
background: lime;
color: black;
transform: rotateY(180deg) translateZ(50px);
}
.right {
background: rgb(196 0 0 / 70%);
transform: rotateY(90deg) translateZ(50px);
}
.left {
background: rgb(0 0 196 / 70%);
transform: rotateY(-90deg) translateZ(50px);
}
.top {
background: rgb(196 196 0 / 70%);
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
background: rgb(196 0 196 / 70%);
transform: rotateX(-90deg) translateZ(50px);
}
/* Make the table a little nicer */
th,
p,
td {
background-color: #eeeeee;
padding: 10px;
font-family: sans-serif;
text-align: left;
}
结果
要配置的第二个元素是观察者的位置,使用 perspective-origin 属性。默认情况下,透视以观察者为中心,这并非总是合适的。
更改透视原点
此示例显示了具有常用 perspective-origin 值的立方体。
HTML
<section>
<figure>
<figcaption><code>perspective-origin: top left;</code></figcaption>
<div class="container">
<div class="cube po-tl">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: top;</code></figcaption>
<div class="container">
<div class="cube po-tm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: top right;</code></figcaption>
<div class="container">
<div class="cube po-tr">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: left;</code></figcaption>
<div class="container">
<div class="cube po-ml">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 50% 50%;</code></figcaption>
<div class="container">
<div class="cube po-mm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: right;</code></figcaption>
<div class="container">
<div class="cube po-mr">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom left;</code></figcaption>
<div class="container">
<div class="cube po-bl">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom;</code></figcaption>
<div class="container">
<div class="cube po-bm">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: bottom right;</code></figcaption>
<div class="container">
<div class="cube po-br">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: -200% -200%;</code></figcaption>
<div class="container">
<div class="cube po-200200neg">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 200% 200%;</code></figcaption>
<div class="container">
<div class="cube po-200200pos">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
<figure>
<figcaption><code>perspective-origin: 200% -200%;</code></figcaption>
<div class="container">
<div class="cube po-200200">
<div class="face front">1</div>
<div class="face back">2</div>
<div class="face right">3</div>
<div class="face left">4</div>
<div class="face top">5</div>
<div class="face bottom">6</div>
</div>
</div>
</figure>
</section>
CSS
/* perspective-origin values (unique per example) */
.po-tl {
perspective-origin: top left;
}
.po-tm {
perspective-origin: top;
}
.po-tr {
perspective-origin: top right;
}
.po-ml {
perspective-origin: left;
}
.po-mm {
perspective-origin: 50% 50%;
}
.po-mr {
perspective-origin: right;
}
.po-bl {
perspective-origin: bottom left;
}
.po-bm {
perspective-origin: bottom;
}
.po-br {
perspective-origin: bottom right;
}
.po-200200neg {
perspective-origin: -200% -200%;
}
.po-200200pos {
perspective-origin: 200% 200%;
}
.po-200200 {
perspective-origin: 200% -200%;
}
/* Define the container div, the cube div, and a generic face */
.container {
width: 100px;
height: 100px;
margin: 24px;
border: none;
}
.cube {
width: 100%;
height: 100%;
perspective: 300px;
transform-style: preserve-3d;
}
.face {
display: block;
position: absolute;
width: 100px;
height: 100px;
border: none;
line-height: 100px;
font-family: sans-serif;
font-size: 60px;
color: white;
text-align: center;
backface-visibility: visible;
}
/* Define each face based on direction */
.front {
background: rgb(0 0 0 / 30%);
transform: translateZ(50px);
}
.back {
background: lime;
color: black;
transform: rotateY(180deg) translateZ(50px);
}
.right {
background: rgb(196 0 0 / 70%);
transform: rotateY(90deg) translateZ(50px);
}
.left {
background: rgb(0 0 196 / 70%);
transform: rotateY(-90deg) translateZ(50px);
}
.top {
background: rgb(196 196 0 / 70%);
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
background: rgb(196 0 196 / 70%);
transform: rotateX(-90deg) translateZ(50px);
}
/* Make the layout a little nicer */
section {
background-color: #eeeeee;
padding: 10px;
font-family: sans-serif;
text-align: left;
display: grid;
grid-template-columns: repeat(3, 1fr);
}
结果
完成此操作后,你可以在 3D 空间中处理元素。
另见
- CSS
transform属性和CSS<transform-function>数据类型 - 各个变换属性:
translate、rotate和scale(没有skew属性) - 将设备方向与 3D 变换一起使用
- CSS 3D 变换简介(David DeSandro 的博客文章)
- CSS 变换演练场(用于可视化 CSS 变换功能的在线工具)