应使用 CSS 自定义属性统一动画时长:在 :root 中定义 --anim-duration-short、--anim-duration-base、--anim-duration-long 等变量,所有动画引用这些变量;JS 动画需同步读取并转换为毫秒;配套规范 transition-property 和 easing,并通过工具约束与团队共识保障落地。

animation-duration 值分散在各处,怎么收口?
直接全局搜索 animation-duration 或 animating 类名,大概率会发现值散落在组件、页面、工具类里:有的写 0.2s,有的用 250ms,还有的甚至出现 0.35s 这种非标数值。这种分散写法会导致动效节奏混乱,维护时改一个时长要满项目搜三遍。
解决方式不是靠人盯,而是用 CSS 自定义属性统一锚点:
:root {
--anim-duration-short: 0.15s;
--anim-duration-base: 0.25s;
--anim-duration-long: 0.4s;
--anim-easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
}后续所有动画都只引用这些变量,比如 transition: all var(--anim-duration-base) var(--anim-easing-standard);。这样改节奏只需调根变量,无需碰业务代码。
不同交互类型该配什么 duration?
不是所有动画都该用同一个时长。用户对反馈速度的预期不同:按钮点击需要快响应,模态框入场需稍缓以留出视觉辨识时间,而加载骨架屏的循环动画则要更轻快避免焦躁。
立即学习“前端免费学习笔记(深入)”;
-
0.15s:微交互动效(hover 色块变化、icon 旋转、输入框 focus 边框) -
0.25s:标准交互反馈(按钮点击态、下拉展开、标签切换) -
0.4s:容器级动效(Modal 进出场、侧边栏滑入、列表项淡入) - 避免使用
0.3s、0.35s等中间值——它们既不够快又不够稳,容易显得“卡顿”
JS 控制动画时长和 CSS 不一致怎么办?
常见于用 element.animate() 或第三方库(如 Framer Motion)驱动动画,但 JS 里硬编码了 duration: 300,而 CSS 里却是 --anim-duration-base: 0.25s。结果就是视觉节奏割裂,尤其在主题切换或动态调整动效开关时更明显。
推荐做法是把时长变量同步到 JS 环境:
const durations = getComputedStyle(document.documentElement);
const baseDuration = parseFloat(durations.getPropertyValue('--anim-duration-base')) * 1000; // ms
// 后续传给 element.animate({ ... }, { duration: baseDuration })如果用 React,可封装成 hook 读取并监听 :root 变化;Vue 则可用 computed 绑定 getComputedStyle 结果。
动画时长统一后,还要注意 easing 和触发时机
只统一时长远远不够。两个 0.25s 动画,一个用 linear,一个用 cubic-bezier(0.4, 0, 0.2, 1),实际观感差异极大。同样,transition 写在 :hover 上,但没配 transition-property,导致所有属性都动,拖慢渲染。
建议配套规范:
- 所有
transition必须显式声明property,例如transition: opacity var(--anim-duration-base) var(--anim-easing-standard); - 关键帧动画(
@keyframes)优先复用已定义的时长变量,避免单独写死 - 禁用
transition: all—— 它会让box-shadow、transform、color全部参与过渡,既难控节奏,也易引发重排
真正难的不是定几个数字,而是让所有人(包括新来的同事、外包同学)在写第一行动画时,就本能地去查 :root 里的变量,而不是随手敲个 0.3s。这需要配合代码检查(ESLint / Stylelint 规则)、PR 模板提醒,以及设计师与前端对「0.25s 是什么感觉」达成共识。










