CSS自定义属性与CSS变量是否存在区别?
嘿,这个问题确实容易让人摸不着头脑,我来给你掰扯清楚~
首先明确:咱们日常嘴里说的「CSS变量」,其实就是官方标准里的「CSS自定义属性」——这俩是同一个东西的不同叫法,只是“变量”这个名字更接地气,大家就传开了。
那MDN文档里那句“请记住,这些是自定义属性,而非真正的CSS变量”到底啥意思?核心区别在于值的计算时机和特性:
- 咱们熟悉的预处理器变量(比如Sass、Less里的
$color)是静态的:预编译的时候就把变量值直接替换到代码里,编译完就固定死了,后续没法动态改变。 - 而CSS自定义属性(也就是咱们说的CSS变量)是动态的:它的值是在浏览器渲染元素的时候才会实时计算,而且会遵循CSS的继承规则,受DOM上下文影响。
举个直观的例子对比:
预处理器变量(静态)
$base-font: 16px; .text { font-size: $base-font; }
编译成CSS后就是:
.text { font-size: 16px; }
不管后续怎么改,这个16px都是固定的。
CSS自定义属性(动态)
:root { --base-font: 16px; } .text { font-size: var(--base-font); } .container { --base-font: 20px; }
当浏览器渲染.container里的.text元素时,会优先使用.container里定义的--base-font:20px,而不是根元素的16px——这个值是渲染时才确定的,甚至还能通过JS动态修改,比如:
document.documentElement.style.setProperty('--base-font', '22px');
页面上所有用到var(--base-font)的元素都会立刻更新样式,这是预处理器变量做不到的。
MDN里说的“值会在需要时计算,而非存储起来供其他规则使用”,其实就是在强调这种动态性:比如你不能像用静态变量那样,把自定义属性的计算结果“存”下来给别的规则用,每次调用var(--xxx)时,浏览器都会重新根据当前元素的上下文去查找、计算它的值。
举个例子:
:root { --width: 100px; --half-width: calc(var(--width) / 2); } .box { --width: 200px; width: var(--half-width); /* 这里会计算出100px,而不是50px */ }
如果是静态变量,--half-width会固定是50px,但CSS自定义属性会在渲染.box时,重新用.box的--width:200px去计算calc(200px/2),得到100px。
说白了,MDN这句话是在提醒咱们:别把CSS自定义属性当成静态的预处理器变量,它本质是个可以动态变化、继承的CSS属性,只是因为能像变量一样复用,才被大家叫做“CSS变量”而已~
内容的提问来源于stack exchange,提问作者Josh Withee

