var(--x)在@keyframes中无效,因规范禁止运行时求值;必须用calc(var(--x))在动画元素上引用,且需显式单位、默认值及Safari 16.4+兼容。

因为 @keyframes 是静态规则,不参与运行时变量求值,var(--x) 在关键帧里直接被忽略,整条声明可能失效。
为什么 var(--x) 在 @keyframes 里根本不起作用
CSS 变量的值是在元素渲染时才计算的,而 @keyframes 块在样式表解析阶段就被固定下来,浏览器只接受字面量、calc() 或函数(如 cubic-bezier())。你写 transform: translateX(var(--dist)),浏览器不报错,但会当作无效声明跳过——DevTools 里这条属性会被划掉或根本不出现。
这不是浏览器 bug,是规范行为:变量没有“上下文”可绑定,@keyframes 不继承、不查找、不延迟求值。
calc(var(--x)) 是唯一合法入口,但括号和单位不能错
必须用 calc() 包一层,才能让变量“挤进”关键帧。但它有硬性语法约束:
立即学习“前端免费学习笔记(深入)”;
-
calc(var(--x))✅;calc var(--x)❌(括号缺一不可) - 如果
--x定义为100(无单位),得写calc(var(--x) * 1px);若定义为100px,就别再乘单位,否则 Safari 可能拒绝解析 -
calc(var(--x) * 2)在 Safari 15.4 之前不支持;calc(100% / var(--speed))需 Safari 16.4+ 才稳定 - 变量必须定义在触发动画的元素上,
:root里定义的不会被读取——哪怕名字一样,也得在目标元素上显式设置,比如.item { --offset: 200px; }
想让 --color 或 --angle 真正动起来?用 @property
如果你要动画的是变量本身(比如渐变角度从 0deg 到 360deg),calc() 救不了——它只能把变量转成值,不能让变量参与插值。这时必须用:
-
@property --grad-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }</angle>—— 缺任一参数都注册失败(DevTools 里该规则会变灰) - 然后在
@keyframes中只改变量:to { --grad-angle: 360deg; } - 确保
background-image: linear-gradient(var(--grad-angle), ...)写在同一个元素上,且该元素应用了animation - 注意:
@property不解决display、opacity这类非插值属性的变量绑定问题,那些仍需靠 class 切换或 JS 控制
Tailwind 用户:自定义动画必须配对写进 tailwind.config.js
Tailwind 不扫描 CSS 文件里的 @keyframes,所有动画必须显式注册:
-
keyframes必须放在theme.extend.keyframes下,键名必须是字符串(如'spin-alt'),不能是变量或数字 -
animation必须在theme.extend.animation里用完全一致的名字绑定,且值是完整声明:'spin-alt': 'spin-alt 1s ease-in-out infinite' - 漏掉
infinite或单位(如写1s而不是1000ms)会导致动画播完就停 - 改完配置后务必运行
npx tailwindcss -o ./dist/tailwind.css,打开输出文件搜索@keyframes spin-alt,搜不到说明配置没生效
最容易被忽略的是变量作用域——你以为 :root 里定义了就能用,其实 @keyframes 根本看不见;还有 @property 的 syntax 和 initial-value 必须严格匹配,差一个字符,变量就退化成静态重绘。


















