必须在元素上绑定 animation-duration 而非 @keyframes 内使用 css 变量,因规范禁止在 @keyframes 中解析变量;正确做法是将变量定义在元素上,用 var(--dur, 0.4s) 绑定时长,并避免简写、确保单位统一、注意 js 修改时机与媒体查询覆盖。

能动态调速,但必须绕开 @keyframes 内部引用变量这个死路——直接在元素上绑定 animation-duration 才可靠。
为什么不能在 @keyframes 里写 var(--dur)
浏览器规范明确禁止在 @keyframes 块内解析 CSS 变量作为数值参与计算或插值。你写 transform: translateX(var(--offset)); 或 animation-timing-function: steps(var(--step-count));,结果不是报错,而是整条声明被静默忽略。动画会退回到默认行为(比如 ease),打字机变滑动,旋转变卡顿。这不是兼容性问题,是规范层的硬限制。
正确做法:变量定义在元素上,animation-duration 直接绑定
把变量挂载到触发动画的元素(或其祖先)上,再用 var() 绑定到动画时长属性。这是唯一被所有现代浏览器稳定支持的路径。
- 必须拆开写,别用
animation简写:简写中嵌变量易因缺值或类型错导致整条声明失效 - 务必带 fallback:如
animation-duration: var(--dur, 0.4s);,否则未声明变量时取默认0s,动画不播 - 单位不能省:
var(--dur, 400ms)和var(--dur, 0.4s)都合法,但混用可能引发可读性混乱,建议统一用ms处理亚秒级动画
示例:
.loader {
--dur: 300ms;
animation-duration: var(--dur, 300ms);
animation-timing-function: cubic-bezier(var(--x1, 0.25), var(--y1, 0.1), var(--x2, 0.25), var(--y2, 1));
animation-name: spin;
}
JS 动态改速时要注意挂载时机
用 JS 修改 style.setProperty('--dur', '200ms') 有效,但前提是动画已通过 CSS 触发并挂载。如果元素刚插入 DOM 就立刻改变量,部分浏览器(尤其是旧版 Safari)可能来不及响应。
- 确保元素已渲染:可用
requestAnimationFrame或getComputedStyle触发重排后操作 - 避免高频修改:连续多次设
--dur可能触发多余重绘,建议加防抖或只在用户明确操作(如滑块拖动)后更新 - 注意媒体查询覆盖:如果在
@media中重写了animation-duration,JS 设置的变量可能被静态值覆盖,优先级更高
容易被忽略的节奏陷阱
光调 animation-duration 不够——同一个 0.3s,配 linear 是机械感,配 cubic-bezier(0.34, 1.56, 0.64, 1) 就有轻弹反馈;而 steps(8) 这类函数本身不接受变量,得靠改 animation-duration + 固定步数来间接控速。更隐蔽的是:duration 缩到 100ms 以下,人眼就难识别为“动画”,容易误判为闪烁或卡死。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











