@property 是唯一能让 CSS 变量带明确数据类型的机制,通过 syntax 和 inherits 声明使浏览器能正确执行数字插值、过渡与动画,避免因类型模糊导致的失效、卡顿或静默错误。

为什么 @property 能解决传统 CSS 动画的类型模糊问题
直接说结论:@property 是唯一能让 CSS 变量带明确数据类型的机制。没有它,var(--opacity) 或 var(--scale) 在动画中只是字符串,浏览器无法预判该按数字插值还是颜色混合——导致 transition 失效、@keyframes 卡顿、甚至静默失败。
典型症状包括:明明改了变量值,元素却不渐变;用 calc(var(--x) * 2) 报错;JS 修改变量后动画跳变。这些都不是写法错误,而是类型缺失引发的底层解析歧义。
@property 的声明必须包含 syntax 和 inherits
漏掉任一参数,变量就退化为普通自定义属性,失去动画支持:
-
syntax决定可接受的值范围,例如"<number>"、"<color>"、"<length>",不支持复合语法如"<number> | <color>" -
inherits控制是否继承父级值,动画场景下通常设为false,避免意外覆盖 - 必须在
:root或具体选择器中声明,不能放在媒体查询或嵌套规则里
正确示例:
立即学习“前端免费学习笔记(深入)”;
/* ✅ 支持 transition 的数字型变量 */
@property --progress {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
<p>.progress-bar {
width: calc(var(--progress) * 100%);
transition: width 0.3s ease;
}和 JS 配合时,setProperty() 必须传原始类型值
JS 修改 @property 变量时,如果传字符串(比如 '0.7'),部分浏览器会拒绝解析——即使语法匹配。必须确保类型严格对应 syntax 声明:
- 数字型:
element.style.setProperty('--progress', 0.7)(不是'0.7') - 颜色型:
element.style.setProperty('--bg', '#ff6b6b')(字符串合法,因<color>接受十六进制) - 长度型:
element.style.setProperty('--size', '16px')(必须带单位,<length>不接受纯数字)
错误示范:el.style.setProperty('--progress', '70%') —— % 不属于 <number> 语法,动画中断。
兼容性与降级策略不可省略
@property 目前仅 Chromium 内核(Chrome 110+、Edge 110+、Opera 96+)和 Safari 16.4+ 支持,Firefox 仍无计划。实际项目中必须考虑 fallback:
- 用
@supports (@property: --x) { ... }包裹现代逻辑 - 降级方案不是“不加动画”,而是回退到 class 切换或 JS-driven
requestAnimationFrame - 切勿在
@property声明中依赖未被广泛支持的syntax值,如"<image>"或自定义函数
最易被忽略的一点:动画触发依赖变量值“变化”,但若 JS 连续两次设相同数值(如都设 0.5),浏览器不会重绘——需手动触发重排或加微小扰动(+ Number.EPSILON)。


















