因为浏览器默认只对已知可动画属性(如color、opacity、transform)插值,自定义属性--my-color无语义时被忽略;需用@property注册syntax(如"")并设inherits:false,才能触发transition插值。

为什么直接用 transition 动不了自定义 CSS 属性?
因为浏览器默认只对「已知可动画的属性」(如 color、opacity、transform)做插值计算。你写 transition: --my-color 0.3s,浏览器根本不知道 --my-color 是颜色、数字还是字符串,直接忽略过渡——控制台不会报错,但动画就是不触发。
必须先用 @property 告诉浏览器:这是个颜色型变量
@property 的核心作用不是“声明变量”,而是“注册动画语义”。没它,--my-color 就是普通字符串;加了它并指定 syntax: "<color>"</color>,浏览器才肯在 transition 过程中对 RGB 值做线性插值。
实操要点:
-
name必须带双横线前缀,如--my-color,且不能省略引号 -
syntax要严格匹配值类型:"<color>"</color>对应red/#fff/rgb(0,0,0);"<number>"</number>才能过渡数字 -
inherits设为false更安全——避免意外继承导致插值异常 - 必须写在 :root 或具体选择器里,但推荐统一放在 :root 下
示例:
立即学习“前端免费学习笔记(深入)”;
@property --my-color {
syntax: "<color>";
inherits: false;
initial-value: #007bff;
}
transition + 自定义属性的实际写法和常见翻车点
声明完 @property 后,才能在元素上用 transition 绑定该变量。注意:transition 目标是变量名,不是它的值;且要确保变量被实际用于可渲染属性(比如 color 或 background-color)。
容易出问题的地方:
- 漏掉
@property声明 → 动画静止,无提示 -
syntax写成"<length>"</length>却赋值red→ 浏览器静默忽略该变量变更,颜色卡死 - 在伪元素或 display: none 元素上尝试动画 → 变量会变,但不触发重绘,看起来像没动
- 同时过渡多个自定义属性时,每个都得单独写
transition,不能合并简写(transition: --a, --b 0.3s有效,但transition: all 0.3s无效)
最小可行代码:
:root {
@property --my-color {
syntax: "<color>";
inherits: false;
initial-value: #007bff;
}
}
.box {
background-color: var(--my-color);
transition: --my-color 0.3s ease;
}
.box:hover {
--my-color: #ff6b6b;
}
兼容性与降级建议
@property 目前仅 Chromium 内核(Chrome 110+、Edge 110+、Opera 96+)和 Safari 16.4+ 支持,Firefox 完全不支持。这意味着靠它做核心动效存在风险。
如果必须兼容 Firefox 或旧 Chrome:
- 用 JavaScript 拆解颜色(如
rgb()→ 数组),手动requestAnimationFrame插值,再 setStyle - 或降级为 class 切换 + 原生属性过渡(
background-color),把@property当增强层 - 别在关键路径(如按钮悬停反馈)上只依赖它——用户看不到动画时,会以为交互失效
真正难的不是写对语法,而是判断什么时候该用它、什么时候该绕开它。



















