@property 必须同时指定 syntax 和 inherits 才能启用自定义属性动画,syntax 决定值类型解析规则(如 、、),inherits 控制继承行为;js 修改时传值类型必须严格匹配 syntax,且 initial-value 也需符合类型要求。

因为没用 @property 声明类型,浏览器把 --x 当成纯字符串,根本不会尝试插值。
为什么 transition: --opacity 0.3s 没反应
自定义属性默认不可动画——这不是 bug,是规范行为。CSS 动画引擎只对明确可插值的属性(如 opacity、transform)做数值计算,而 var(--opacity) 在未声明前只是文本替换,连“这是个数字”都识别不出来。
常见症状包括:
- 鼠标悬停后背景色或尺寸直接跳变,没有过渡
-
calc(var(--scale) * 100px)在 JS 修改变量后报错或计算中断 - 开发者工具里看到变量值变了,但视觉毫无响应
这些都不是写错 transition,而是变量本身没被赋予动画资格。
@property 必须同时写 syntax 和 inherits
漏掉任一参数,@property 就退化为普通 CSS 变量声明,失去所有动画能力。
syntax 决定浏览器怎么解析值:
- 数字控制缩放、透明度:
syntax: "<number>"</number>(不能写"<length>"</length>然后传0.7) - 长度控制位置、尺寸:
syntax: "<length>"</length>(必须带单位,如16px、2rem) - 颜色控制渐变、背景:
syntax: "<color>"</color>(支持#fff、rgb()、hsl())
inherits: false 是绝大多数场景的合理选择;设为 true 可能导致子元素意外触发重绘,尤其在动画中。
JS 修改 @property 变量时传值类型必须严格匹配
即使语法看着对,类型错一点,动画就断。
- 数字型变量:
el.style.setProperty('--progress', 0.7)✅(传Number)
el.style.setProperty('--progress', '0.7')❌(字符串,部分 Chromium 版本拒绝解析) - 长度型变量:
el.style.setProperty('--size', '24px')✅
el.style.setProperty('--size', 24)❌(缺单位,<length></length>不接受纯数字) - 颜色型变量:
el.style.setProperty('--bg', '#ff6b6b')✅(字符串合法)
el.style.setProperty('--bg', 'red')✅(<color></color>支持关键字)
特别注意:'70%' 不属于 <number></number>,也不属于 <length></length>,传给任一者都会导致动画静默失效。
兼容性兜底不能只靠 @supports
@supports (@property: --x) 在旧版 Safari(如 16.3)里会误返回 true,结果动画不执行也不报错。
更可靠的检测方式是用 JS:
if (CSS.supports('transition', '--x 1s')) {
document.documentElement.classList.add('supports-property');
}
然后在 CSS 中用 .supports-property .target { transition: --x 0.3s; } 控制启用范围。Firefox 目前完全不支持 @property,降级方案得是 class 切换或 requestAnimationFrame 驱动,不是“不加动画”就完事。
真正容易被忽略的是:initial-value 的值也必须符合 syntax 类型——比如 initial-value: 0 对 <length></length> 是非法的,得写 initial-value: 0px。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











