@property 是唯一能让 CSS 变量参与原生动画的方式,因其为变量赋予类型、初始值和继承性,使浏览器能执行合法插值;否则 transition: --bg 0.3s 会被静默忽略,变量仅作字符串处理,无法触发任何过渡效果。

@property 是唯一能让 CSS 变量参与原生动画和 transition 的方式,不加它,--color、--size 这类变量在动画中只是字符串,浏览器无法插值。
为什么直接写 transition: --bg 0.3s 完全无效
浏览器看到 --bg 时,只当它是未解析的字符串,不知道该按颜色混合、数字线性插值,还是跳变。哪怕你写了 background-color: var(--bg),只要没用 @property 声明类型,transition 就被静默忽略。
- 典型症状:hover 时背景色“啪”一下跳到新值,毫无缓动
- DevTools 里查不到该变量注册成功(
@property声明失败时不会报错,只丢弃) -
calc(var(--size) * 2)报错,因为--size没类型,calc()拒绝运算
@property 声明必须同时满足三个硬性条件
漏掉任意一项,变量就退化为普通字符串变量,失去动画能力:
-
syntax必须是带单引号的字符串,且内容严格匹配标准类型关键词,例如'<color>'</color>、'<length>'</length>、'<number>'</number>—— 写成"<color>"</color>(双引号)或<color></color>(无引号)都会失效 -
inherits必须显式写true或false,不能省略;动画场景下几乎都用inherits: false -
initial-value必须是字符串字面量,且类型与syntax完全一致:若syntax: '<length>'</length>,则initial-value: '16px'✅,'16'❌;若syntax: '<number>'</number>,则initial-value: '2.5'✅,'2.5px'❌
常见 syntax 类型及 JS 设置时的对应写法
类型声明不是摆设,JS 动态修改时传错类型,动画会立刻中断:
立即学习“前端免费学习笔记(深入)”;
-
syntax: '<color>'</color>→ JS 中用el.style.setProperty('--bg', '#ff6b6b')(字符串合法) -
syntax: '<number>'</number>→ JS 中必须用el.style.setProperty('--opacity', 0.8)(传 Number,不是'0.8') -
syntax: '<length>'</length>→ JS 中必须带单位:el.style.setProperty('--size', '24px')(24或'24'都 ❌) - 组合类型如
'<length> | <percentage>'</percentage></length>允许两种取值,但 JS 设置时仍需严格匹配其中一种格式
@property 的位置和兼容性陷阱
它不是普通 CSS 规则,对上下文极其敏感:
- 必须写在
:root或独立<style>块最顶部,不能嵌套在@media、@layer或选择器内部 - 目前仅 Chromium(Chrome 110+、Edge 110+)和 Safari 17.4+ 支持;Firefox 仍无实现计划
- 必须用
@supports (property: --x)包裹现代逻辑,否则旧引擎可能因语法不识别而丢弃整段样式 - 别指望
<image></image>或<transform-function></transform-function>能稳定工作——它们虽在 spec 中,但实际支持度极低,当前生产环境应规避
最容易被忽略的是:即使 @property 声明成功,如果后续把变量用在 border、margin 这类简写属性里,插值依然会失败。必须拆成 border-color、margin-top 等具体子属性,浏览器才真正能做类型化插值。


















