Rules · 5 条
五条铁律,和一页「不该动」
做动效的能力人人都有,克制才稀缺。真正拉开差距的不是你会多少种曲线,而是你知道哪一次点击不该有动画。
五条铁律
- 01
只动 transform 和 opacity
改 width / left / top / margin 会触发重排,整条渲染流水线得从头再跑一遍。transform 和 opacity 可以只走合成层。
违反会怎样:下面那两栏就是这条的现场:同一段动画,一个动 left,一个动 transform。
- 02
进场比退场慢
用户等的是「出现」,不会等「消失」。常见配比是进场 250ms、退场 150ms。
违反会怎样:退场和进场一样慢,界面会像在慢吞吞地收摊。
- 03
距离决定时长
同样 300ms,位移 8px 显得从容,位移 300px 显得仓促。位移翻倍,时长至少 ×1.4。
违反会怎样:全站统一 300ms 是最常见的偷懒,结果是小元素拖沓、大面板仓促。
- 04
同类动作只用一个时长
一屏里所有「进入」用同一个数,所有「离开」用同一个数。节奏才能成立。
违反会怎样:每张卡片随机 200~400ms,用户会觉得这个界面不稳定。
- 05
减少动效是换一种交代,不是取消交代
开启 prefers-reduced-motion 后,应该直接呈现终态,让用户确认「事情发生了」;而不是什么都不发生。
违反会怎样:直接不播 —— 用户点了按钮,界面毫无反应,他会以为坏了。
铁律 1 的现场
同样 96 个元素,一个动 left、一个动 transform。 两栏先后各测一次,避免互相干扰。先量布局耗时(这才是规则的机制),再播一遍看帧率。
- 帧率
- —
- 布局耗时
- —
- 掉帧
- —
- 帧率
- —
- 布局耗时
- —
- 掉帧
- —
读数是你这台设备此刻的真实表现。transform 可以交给合成线程,left 必须每帧回主线程重算布局 —— 这个差别在弱设备、大 DOM、主线程同时在忙别的时才会被放大。 强设备上两栏接近是正常的,不代表规则不成立,只代表你还没赌到会被它咬的那台机器。
这里不该动
判断「什么时候不动」比「什么时候动」难得多。下面这几类,默认答案就是不要动。
高频操作
滚动、输入、每次按键都触发的东西。第 50 次看到它只会烦。
系统级反馈
保存成功、发送失败。这类要的是立刻看清结果,不是看动画。
内容阅读路径
正文进入、图片切换的入场。读者是来读字的,不是来看转场的。
用户已经等过的地方
加载完成后就别再「庆祝」了,等待已经付过成本。
长列表的重复元素
第 20 项还做错峰入场,只会让最后几项出现得更晚。
表单报错
抖动会加重焦虑。报错要稳、要显眼,不要活泼。
减少动效的正确做法
铁律 5 展开说一遍。区别只有一句话:用户要知道「事情发生了」。
✗ 直接不播
@media (prefers-reduced-motion: reduce) {
/* 动画没了,用户也不知道点没点上 */
.dialog { animation: none; }
}✓ 直接到终点
@media (prefers-reduced-motion: reduce) {
/* 时长归零,终态照常呈现 */
.dialog {
animation-duration: 0.001ms;
animation-iteration-count: 1;
}
}发布前自检表
逐条对一遍,有一条不成立就先别发。
- 动画只作用在 transform / opacity 上
- 进场 ≤ 400ms,退场明显更快
- 开启减少动效后,仍能直接看到终点状态
- 动画中途被打断时,从当前值继续而不是跳回起点
- 没有任何信息只能靠动画才能理解
- 首屏没有自动播放的动画
- 深色 / 浅色两套主题都实际看过
- 键盘操作路径上没有被动画挡住