B05 变换过渡与动画

2026-10-31 17:150 阅读约 10 分钟CSS

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. 悬停按钮,确认上移 1 像素并有背景过渡。
  2. 打开 Rendering 面板勾选 Layer borders,确认卡片在悬停时进入独立合成层。
  3. 把 transform: translateY(-2px) 改为 margin-block-start: -2px,对比是否有布局抖动。
  4. 系统开启「减少动态效果」,刷新,确认所有动效关闭。
检查项 预期结果 说明
过渡生效 悬停时有 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 节代码

参考文献

[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

0/2000

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