@property能拦截非法颜色值,因其通过syntax: ""强制运行时类型校验,赋值非法时(如'12px')静默失败并保持上一合法值,而var()仅语法解析、不校验语义。

为什么 @property 能拦截非法颜色值
浏览器对 var(--color) 的解析是“尽力而为”:只要语法能过,哪怕语义错(比如 --color: 12 缺单位),也静默丢弃整条声明,不报错、不警告。而 @property 是唯一能在赋值阶段就卡住非法值的机制——它让 CSS 变量第一次拥有了运行时类型校验能力。
关键点在于:syntax: "<color>"</color> 不只是文档说明,而是强制契约。一旦注册,所有后续对 --color 的赋值都会被浏览器按该类型实时校验:
-
element.style.setProperty('--color', '12px')→ 静默失败,变量值保持上一次合法值 -
element.style.setProperty('--color', '#ff6b6b')→ 成功,<color></color>明确接受十六进制 -
element.style.setProperty('--color', 'transparent')→ 成功,transparent是标准颜色关键字 -
element.style.setProperty('--color', 'rgb(255, 0,')→ 失败,语法不完整,触发回退
@property 声明必须带 inherits 和 syntax
漏掉任一参数,@property 就退化成普通自定义属性,失去类型检查和动画支持。这不是可选配置,而是硬性要求。
常见错误写法:
-
@property --bg { syntax: "<color>" }</color>→ 缺inherits,Chrome 会忽略整个规则 -
@property --bg { inherits: false }→ 缺syntax,变量无类型,仍可被设为任意字符串 -
@property --bg { syntax: "<color> | <image>" }</image></color>→ 语法不被支持,浏览器静默跳过
正确写法必须完整:
@property --bg {
syntax: "<color>";
inherits: false;
initial-value: #fff;
}</color>
JS 设置 @property 变量时的类型陷阱
即使 @property 声明了 syntax: "<number>"</number>,JS 传字符串也会导致部分浏览器拒绝解析——不是兼容性问题,而是类型契约被违反。
- 数字型:
el.style.setProperty('--opacity', 0.7)✅(传原始 number)el.style.setProperty('--opacity', '0.7')❌(字符串不匹配<number></number>) - 长度型:
el.style.setProperty('--size', '16px')✅(<length></length>必须带单位)el.style.setProperty('--size', 16)❌(纯数字不合法) - 颜色型:
el.style.setProperty('--hue', '220')❌(<color></color>不接受裸数字)el.style.setProperty('--hue', 'hsl(220, 100%, 50%)')✅
回退值只在未定义或非法时触发,不看语义
var(--color, #000) 的回退逻辑常被误解。它不会因为值“不合理”就触发,只响应两类情况:变量根本没定义,或值本身语法非法(如 --color: rgb(255, 0,)。以下都是合法值,回退不会生效:
-
--color: transparent→ 合法颜色值 -
--color: inherit→ 合法关键字 -
--color: ""(空字符串)→ 语法非法,触发回退 -
--color: none→none不属于<color></color>,触发回退
调试时直接在 DevTools 中悬停失效的 var(),看提示是 “variable is undefined” 还是 “invalid value”——前者补 @property 声明,后者查 JS 赋值内容或 CSS 中的原始定义。
真正难处理的,是那些看起来“应该失败却没失败”的场景:比如 --size: auto 50% 在 width 上非法,但浏览器只丢弃整条声明,不报错也不留痕迹。这种静默行为才是 @property 最该介入的地方。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











