B05 变换过渡与动画
B05 变换过渡与动画
摘要:
transform改变元素的位置、旋转与缩放,transition在状态切换时补间,animation按关键帧循环。三者都作用于合成层,不改布局,因此性能最好。代价是可访问性:动效必须响应「减少动态效果」偏好,否则会对部分用户造成不适。
关键词:变换,过渡,关键帧,动画,合成层
所属:frontend/css / B-进阶 | 上一篇:B04-伪类与伪元素 | 下一篇:B06-自定义属性与主题
1 引言
动效的作用是提供状态变化的线索,不是装饰。判断一条动效是否合格只需两问:它解释了什么变化、关掉之后是否影响理解。
本文给出三类写法的组合与性能边界。范围见表 1-1。
| 项 | 本文覆盖 | 本文不覆盖 |
|---|---|---|
| 变换 | translate、rotate、scale、transform-origin |
3D 透视矩阵 |
| 过渡 | transition-property、时长、缓动、延迟 |
滚动驱动动画 |
| 动画 | @keyframes、animation-*、播放状态 |
JavaScript 动画库 |
| 可访问性 | prefers-reduced-motion |
前庭失调的完整规范 |
2 预备知识
| 项 | 要求 | 核对方式 |
|---|---|---|
| 环境 | 本地服务器可用 | 浏览器能打开 localhost |
| 文件 | css-practice/motion.html |
编码 UTF-8 |
| 浏览器 | Chrome 130+,Rendering 面板 | 能看到合成层 |
| 前置 | B03 | 理解层叠与上下文 |
3 原理与实现
3.1 三个阶段
一条动效由起始状态、过渡或关键帧、结束状态三部分组成,如图 3-1 所示。
flowchart LR
A["默认状态"] -->|"状态变化<br/>hover / 类名切换"| B["过渡<br/>transition 补间"]
B --> C["目标状态"]
D["@keyframes 定义关键帧"] --> E["animation 循环或播放一次"]
E --> C
C --> F{"prefers-reduced-motion"}
F -->|"reduce"| G["关闭动画"]
图 3-1 动效的三个阶段与降级分支
图上可见:
transition只响应状态变化,animation由关键帧驱动;两者都可以被减少动效偏好整体关闭。
3.2 三类写法
/* 运行环境:Chrome 130+;css-practice/motion.css */
.button {
transition: transform 160ms ease-out, background-color 160ms ease-out;
}
.button:hover { transform: translateY(-1px); background: #1e40af; }
.button:active { transform: translateY(0); }
.card {
transition: box-shadow 200ms ease, transform 200ms ease;
}
.card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgb(15 23 42 / 0.12); }
@keyframes pulse {
from { opacity: 1; }
to { opacity: 0.4; }
}
.badge {
animation: pulse 1.8s ease-in-out infinite alternate;
}
@media (prefers-reduced-motion: reduce) {
.button, .card, .badge {
transition: none;
animation: none;
transform: none;
}
}
三类写法与性能见表 3-1。
| 写法 | 触发方式 | 是否触发重排 | 适用场景 |
|---|---|---|---|
transform |
状态或类名变化 | 否 | 位移、缩放、旋转 |
transition |
属性值变化 | 否(限合成属性) | 悬停、展开 |
animation |
关键帧驱动 | 否(限合成属性) | 循环提示、加载 |
| 改动宽高 | 任意 | 是 | 尽量用 transform 替代 |
常用变换属性见表 3-2。
| 属性 | 作用 | 注意点 |
|---|---|---|
translate |
位移 | 独立属性,可与 rotate 叠加 |
scale |
缩放 | 不影响布局,周围元素不重排 |
rotate |
旋转 | 默认绕元素中心 |
transform-origin |
变换原点 | 默认 50% 50% |
transform |
组合写法 | 顺序影响结果 |
4 验证与讨论
- 悬停按钮,确认上移 1 像素并有背景过渡。
- 打开 Rendering 面板勾选 Layer borders,确认卡片在悬停时进入独立合成层。
- 把
transform: translateY(-2px)改为margin-block-start: -2px,对比是否有布局抖动。 - 系统开启「减少动态效果」,刷新,确认所有动效关闭。
| 检查项 | 预期结果 | 说明 |
|---|---|---|
| 过渡生效 | 悬停时有 160ms 过渡 | transition |
| 无重排 | 动画期间其它元素不移动 | transform |
| 合成层 | 面板显示独立层 | 性能更好 |
| 减少动效 | 关闭后无动画 | 媒体查询 |
讨论与局限。 transform 会创建层叠上下文,可能改变 z-index 的表现(B03)。另动画时长超过 300 毫秒会让人觉得迟钝,短于 100 毫秒又几乎感觉不到。
5 常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
| 过渡无效果 | 属性不可过渡(如 display) |
改用 opacity 或 transform |
| 动画卡顿 | 改动 width、top 等布局属性 |
改为 transform |
| 悬停后回弹突兀 | 只在悬停态写了 transition | 把 transition 写在默认态 |
| 减少动效设置不生效 | CSS 里没有对应媒体查询 | 补 prefers-reduced-motion 分支 |
| 元素被遮挡 | transform 创建了新上下文 | 调整层级或移除 transform |
6 结论
| 序号 | 结论 | 依据 |
|---|---|---|
| 1 | 动效要解释状态变化,不做装饰 | 图 3-1 |
| 2 | 优先动 transform 与 opacity |
表 3-1 |
| 3 | 时长控制在 100 ~ 300 毫秒 | 讨论 |
| 4 | 必须响应减少动效偏好 | 3.2 节代码 |
- 上一篇:B04-伪类与伪元素
- 下一篇:B06-自定义属性与主题
- 返回:B00-总结 | 科目 README
参考文献
[1] MDN Web Docs · 使用 CSS 过渡,https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_transitions/Using_CSS_transitions(访问于 2026-10-31)
[2] MDN Web Docs · prefers-reduced-motion,https://developer.mozilla.org/zh-CN/docs/Web/CSS/@media/prefers-reduced-motion(访问于 2026-10-31)

评论 0
还没有评论,快来抢沙发吧~