WinddSnow

CSS-Transforms-and-Transitions

字数统计: 2.9k阅读时长: 12 min
2026/07/29

第23课:变换与过渡

CSS 提供了两种在不借助 JavaScript 的情况下改变元素外观的机制:变换(Transform)过渡(Transition)。变换通过修改元素的坐标空间实现平移、旋转、缩放和倾斜,且不占据布局空间、不触发回流;过渡则让属性值的变化变得平滑,赋予界面细腻的交互感。两者结合,足以构建流畅的交互动效。本节课将逐层解析 transform 的 2D 与 3D 函数、transition 的精细控制,以及贝塞尔曲线背后的时间函数原理。


1. transform 变换:在不破坏布局的情况下改变元素形态

transform 属性对元素应用矩阵变换,修改其视觉呈现,但不改变元素在文档流中的布局空间。其他元素仍按变换前的位置排列,不会因变换而重新布局。

1
2
3
.box {
transform: translate(50px, 30px);
}

1.1 为什么变换不触发回流?

浏览器的渲染流水线大致为:布局(Layout)→ 绘制(Paint)→ 合成(Composite)transform 发生在合成阶段,仅操作 GPU 上的图层纹理,不会触发前面的布局和绘制步骤。这也是 transform 在动画中性能优于 top/left 等属性的根本原因。

1.2 2D 变换函数

平移:translate()

将元素沿 X 轴和 Y 轴移动。

1
2
3
4
5
6
7
8
/* 向右 50px,向下 30px */
transform: translate(50px, 30px);

/* 仅水平移动(Y 默认为 0) */
transform: translateX(50px);

/* 仅垂直移动 */
transform: translateY(-20px);

百分比参照translate() 使用百分比时,参照的是元素自身的尺寸(而非父容器)。这是实现绝对居中定位的关键。

1
2
3
4
5
6
7
/* 经典:绝对定位元素完美居中 */
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

旋转:rotate()

将元素绕指定点旋转。2D 旋转默认绕元素的中心点(可通过 transform-origin 修改)。

1
2
3
4
5
/* 顺时针旋转 45 度 */
transform: rotate(45deg);

/* 负值为逆时针 */
transform: rotate(-20deg);

常用角度单位:

  • deg(度):360deg 为一整圈。
  • rad(弧度):2π rad 为一整圈(约 6.2832rad)。
  • turn(圈):1turn 为一整圈。

缩放:scale()

沿 X 轴和 Y 轴缩放元素。1 为原始尺寸,0 为完全不可见(但元素仍占据空间)。

1
2
3
4
5
6
7
8
/* 宽度缩放到 1.5 倍,高度缩放到 0.8 倍 */
transform: scale(1.5, 0.8);

/* 等比例缩放到 1.2 倍 */
transform: scale(1.2);

/* 水平翻转(scaleX 为负) */
transform: scaleX(-1);

注意scale() 会缩放元素的一切——包括边框、内边距、文字和子元素。缩放中心也是元素中心点。

倾斜:skew()

沿 X 轴和/或 Y 轴倾斜元素,产生“斜体”变形效果。

1
2
3
4
5
6
7
8
/* 沿 X 轴倾斜 15 度 */
transform: skewX(15deg);

/* 沿 Y 轴倾斜 10 度 */
transform: skewY(10deg);

/* 同时倾斜 X 和 Y */
transform: skew(15deg, 10deg);

注意skew() 的简写中若只给一个值,等同于 skewX()。该函数已不常被直接使用,更多被矩阵或工具库替代。

组合变换:空格分隔

多个变换函数可以用空格分隔,书写顺序即执行顺序(从右到左应用,但从视觉上理解为从左到右依次作用即可)。

1
2
3
4
5
/* 先平移,再旋转,再缩放(执行顺序:右→左) */
transform: translateX(100px) rotate(45deg) scale(1.5);

/* 不同顺序,不同结果 */
transform: rotate(45deg) translateX(100px); /* 先旋转坐标系,再沿旋转后的 X 轴平移 */

1.3 transform-origin:变换原点

默认情况下,变换(旋转、缩放、倾斜)以元素的中心点为原点。transform-origin 可修改这个原点的位置。

1
2
3
4
5
6
7
8
/* 以左上角为原点旋转 */
transform-origin: top left;

/* 以元素右下角为原点缩放 */
transform-origin: 100% 100%;

/* 精确像素值 */
transform-origin: 50px 30px;

语法transform-origin: <x> <y> [<z>];(z 用于 3D 变换)。

1.4 3D 变换简介

在 2D 基础上增加 Z 轴深度,需要配合 perspective(透视)才能产生近大远小的立体效果。

1
2
3
4
5
6
7
.scene {
perspective: 600px; /* 父容器设置透视距离,值越小透视越强烈 */
}

.card {
transform: rotateY(30deg); /* 绕 Y 轴旋转,产生翻牌效果 */
}

常用 3D 函数

函数 说明
translateZ(z) 沿 Z 轴平移。
translate3d(x, y, z) 3D 平移。
rotateX(angle) 绕 X 轴旋转(前后翻转)。
rotateY(angle) 绕 Y 轴旋转(左右翻转)。
rotateZ(angle) 绕 Z 轴旋转(等同于 2D 旋转)。
rotate3d(x, y, z, a) 绕任意 3D 向量旋转 a 角度。
scaleZ(z) / scale3d() Z 轴缩放 / 3D 缩放。
matrix3d() 16 个值的 4×4 3D 矩阵。

3D 渲染上下文:给父容器设置 transform-style: preserve-3d,可使子元素的 3D 变换保持独立而非压平。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.card-container {
perspective: 800px;
}
.card {
transform-style: preserve-3d;
transition: transform 0.6s;
}
.card:hover {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
backface-visibility: hidden; /* 隐藏背面 */
}
.card-back {
transform: rotateY(180deg);
}

2. transition 过渡:让属性变化平滑发生

transition 是 CSS 中最简单的动画形式——当元素的指定属性值发生变化时(如悬停、聚焦、类名切换),过渡让这种变化在一段时间内平滑发生,而非瞬间跳变。

2.1 基本语法

transition 是一个简写属性:

1
transition: <property> <duration> <timing-function> <delay>;
1
2
3
4
5
6
7
.button {
background-color: #007bff;
transition: background-color 0.3s ease-in-out;
}
.button:hover {
background-color: #0056b3;
}

2.2 四个子属性详解

子属性 说明 默认值
transition-property 指定哪些 CSS 属性应用过渡。all 表示所有可动画属性。推荐精确指定属性,避免不必要的性能开销。 all
transition-duration 过渡持续时间。单位为 s(秒)或 ms(毫秒)。0s 表示无过渡。 0s
transition-timing-function 时间函数,控制过渡中间各时刻的速率变化。 ease
transition-delay 延迟多久后开始过渡。正值延迟开始,负值立即开始但直接跳到对应时刻的状态。 0s

多个属性的独立过渡:用逗号分隔,可对每个属性设置不同的过渡参数。

1
2
3
4
5
6
7
8
9
10
11
.card {
transition:
transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.5s ease,
background-color 0.2s linear;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
background-color: #f0f0f0;
}

2.3 可过渡的属性

并非所有 CSS 属性都能平滑过渡。通常,数值型或可量化的属性才支持过渡:

类别 示例属性 不可过渡的典型属性
尺寸与间距 widthheightmarginpadding displayposition
颜色 colorbackground-colorborder-color background-imagefont-family
变换 transform
透明度 opacity
位置 topleftrightbottom(需定位元素) float
其他 box-shadowborder-radiusfiltervisibility

性能提示:在过渡或动画中,优先使用 transformopacity,因为它们仅触发合成,不触发布局或绘制。避免过渡 widthheighttopleft 等触发布局的属性。


3. transition-timing-function 与贝塞尔曲线

时间函数是过渡的“性格”所在——它决定了动画在时间轴上的速率分布。

3.1 预设关键字

关键字 对应曲线 视觉感受
linear cubic-bezier(0, 0, 1, 1) 全程匀速,机械感强。
ease cubic-bezier(0.25, 0.1, 0.25, 1) 慢→快→慢,自然默认值。
ease-in cubic-bezier(0.42, 0, 1, 1) 慢→快,用于元素进入屏幕。
ease-out cubic-bezier(0, 0, 0.58, 1) 快→慢,用于元素离开屏幕或强调结束状态。
ease-in-out cubic-bezier(0.42, 0, 0.58, 1) 慢→快→慢,对称曲线,适合循环动画。

3.2 贝塞尔曲线原理

cubic-bezier() 函数接受 4 个参数:(x1, y1, x2, y2),定义了一条三次贝塞尔曲线,用于将时间进度(横轴,0→1)映射为属性变化进度(纵轴,0→1)。

  • 横轴(x)始终是时间比例(0 到 1)。
  • 纵轴(y)是属性值比例(0 到 1,但曲线可超出此范围产生“回弹”效果)。
  • P0 固定为 (0, 0),P3 固定为 (1, 1)。用户定义的 (x1, y1) 是控制点 P1,(x2, y2) 是控制点 P2。
1
2
/* 自定义:快速启动,中间放缓,结尾加速 */
transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);

3.3 常用自定义曲线

效果 曲线 适用场景
弹性回弹 cubic-bezier(0.68, -0.55, 0.27, 1.55) 弹入弹出,活泼灵动。
快速进入 cubic-bezier(0.4, 0, 1, 1) 元素快速飞入。
平滑退出 cubic-bezier(0, 0, 0.2, 1) Material Design 标准退出曲线。
标准曲线 cubic-bezier(0.4, 0, 0.2, 1) Material Design 标准曲线。

4. 综合示例:悬停浮起卡片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<style>
.card {
width: 280px;
padding: 24px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);

/* 指定过渡属性:transform 和 box-shadow */
transition:
transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.card:hover {
transform: translateY(-8px);
box-shadow: 0 12px 30px rgba(0,0,0,0.15);
}
</style>

<div class="card">
<h3>卡片标题</h3>
<p>悬停时,卡片向上浮起 8px,阴影加深扩散,过渡平滑自然。</p>
</div>

课后练习

一、概念自测(选择题 / 填空题)

  1. (单选) 以下哪个 CSS 属性在动画中性能最优,因为它仅触发合成阶段?
    A. width
    B. background-color
    C. transform
    D. box-shadow

  2. (单选) 关于 translate(50%, 50%) 中的百分比值,以下说法正确的是?
    A. 相对于父容器的宽度和高度。
    B. 相对于视口的宽度和高度。
    C. 相对于元素自身的宽度和高度。
    D. 相对于包含块的宽度和高度。

  3. (填空) 要使元素绕其左上角旋转,应设置 transform-origin: ______ ______

  4. (多选) 以下哪些属性可以参与 transition 平滑过渡?
    A. opacity
    B. display
    C. transform
    D. color

二、AI 编程任务:编写面向 AI 的提示词

场景:你需要实现一个图片翻转卡片(Flip Card)效果。要求如下:

  • 卡片正面显示一张图片(占位图),背面显示描述文字。
  • 鼠标悬停时,卡片绕 Y 轴旋转 180 度,显示背面。
  • 正面和背面的切换使用 3D 变换:rotateY
  • 父容器设置 perspective 提供透视效果,卡片设置 transform-style: preserve-3d
  • 正反面均设置 backface-visibility: hidden 防止旋转时穿透显示。
  • 过渡时间 0.6 秒,时间函数使用 ease-in-out
  • 卡片尺寸固定(如 300×200px),有圆角和阴影。

任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成完整的 HTML 和 CSS 代码。提示词中应明确指定透视距离、3D 变换函数、过渡参数以及正反面的定位方式(使用绝对定位叠加)。


课后练习答案

一、概念自测答案

  1. C

    • 解析:transform 仅触发合成阶段,不触发布局和绘制,由 GPU 加速,性能最优。
  2. C

    • 解析:translate() 的百分比值参照元素自身尺寸,这一特性常用于绝对居中。
  3. top left0 0

    • 解析:transform-origin: top left 将变换原点设在元素左上角。
  4. A、C、D

    • 解析:opacitytransformcolor 均可平滑过渡。display 是离散属性,无法过渡。

二、AI 编程任务参考答案(提示词示例)

示例提示词
“请实现一个翻转卡片(Flip Card)组件,纯 HTML + CSS。要求:

  • 卡片外层容器 .card-container 设置 perspective: 1000px
  • 内层 .card 宽 300px,高 200px,设置 transform-style: preserve-3dtransition: transform 0.6s ease-in-out
  • 悬停 .card-container:hover .card 时,.card 执行 transform: rotateY(180deg)
  • .card-front.card-back 使用绝对定位叠放在 .card 内(position: absolute; inset: 0;),均设置 backface-visibility: hidden
  • .card-back 需要预先 transform: rotateY(180deg) 使其初始时隐藏。
  • 正面放一张占位图(https://via.placeholder.com/300x200),背面放描述文字,背面背景为 #f5f5f5,文字居中。
  • 卡片整体有圆角 12px 和阴影。直接输出完整 HTML 文件。”
CATALOG
  1. 1. 第23课:变换与过渡
    1. 1.1. 1. transform 变换:在不破坏布局的情况下改变元素形态
      1. 1.1.1. 1.1 为什么变换不触发回流?
      2. 1.1.2. 1.2 2D 变换函数
        1. 1.1.2.1. 平移:translate()
        2. 1.1.2.2. 旋转:rotate()
        3. 1.1.2.3. 缩放:scale()
        4. 1.1.2.4. 倾斜:skew()
        5. 1.1.2.5. 组合变换:空格分隔
      3. 1.1.3. 1.3 transform-origin:变换原点
      4. 1.1.4. 1.4 3D 变换简介
    2. 1.2. 2. transition 过渡:让属性变化平滑发生
      1. 1.2.1. 2.1 基本语法
      2. 1.2.2. 2.2 四个子属性详解
      3. 1.2.3. 2.3 可过渡的属性
    3. 1.3. 3. transition-timing-function 与贝塞尔曲线
      1. 1.3.1. 3.1 预设关键字
      2. 1.3.2. 3.2 贝塞尔曲线原理
      3. 1.3.3. 3.3 常用自定义曲线
    4. 1.4. 4. 综合示例:悬停浮起卡片
    5. 1.5. 课后练习
      1. 1.5.1. 一、概念自测(选择题 / 填空题)
      2. 1.5.2. 二、AI 编程任务:编写面向 AI 的提示词
    6. 1.6. 课后练习答案
      1. 1.6.1. 一、概念自测答案
      2. 1.6.2. 二、AI 编程任务参考答案(提示词示例)