@keyframes 中 var(--x) 不会插值,因 css 动画仅对白名单属性插值,var() 是运行时字符串替换;需用 @property 显式声明 syntax 和 inherits 才支持平滑动画。

为什么 @keyframes 里用 var(--x) 不会插值
因为浏览器根本没把 --x 当成“可动画值”——它只是字符串替换,不是数值类型。比如你在 @keyframes 里写 transform: translateX(var(--tx));,哪怕 JS 改了 --tx 的值,动画引擎也不会去算中间帧,只会等下一帧直接渲染新值。这不是 bug,是规范行为:CSS 动画只对白名单属性(如 opacity、transform)做插值,而 var() 是运行时文本代入,不参与插值计算。
@property 必须同时声明 syntax 和 inherits
想让 --tx 在动画中真正平滑变化,必须用 @property 显式注册它:
-
syntax决定类型解析规则,比如"<length>"</length>或"<number>"</number>,缺了它浏览器就不知道怎么插值 -
inherits控制是否继承,设为false或true都行,但不能省略——漏掉任一个,@property就退化为普通变量声明,动画能力归零 - 初始值
initial-value也得匹配syntax类型,比如syntax: "<length>"</length>就不能写initial-value: 10,得写initial-value: 10px
示例:
@property --tx {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}</length>
JS 修改变量时类型必须严格匹配 syntax
即使 @property 写对了,JS 改值时传错类型也会让插值中断:
- 如果
syntax: "<length>"</length>,就不能用el.style.setProperty('--tx', '20')(缺单位),得写'20px'或'2rem' - 传
'auto'、'inherit'这类非数值值,插值直接失效,变成跳变 - Chrome/Edge/Safari(≥v115)支持,Firefox 目前不支持
@property动画,别在生产环境依赖它做核心动效
更稳的替代方案:用 transform + transition 替代变量驱动
如果目标只是位移/缩放/透明度过渡,直接用 transform 和 opacity 配 transition 更可靠:
- 不需要
@property,兼容性好(IE10+) - 浏览器原生优化 GPU 加速,不会因 JS 操作失误中断插值
- 避免
calc(var(--x) * 100px)这类嵌套计算,这类表达式在动画中容易卡顿或报错 - 若需 JS 控制进度,优先用
el.animate()或 CSS Houdini 的worklet,而不是靠变量触发 transition
真正容易被忽略的是:你以为在调动画,其实只是在改一个字符串;插值能力不是默认开启的,它需要你亲手告诉浏览器“这个变量有类型,可以算中间值”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











