摘要

  • W3C 2012 年 4 月 10 日发布的首份 CSS Variables 工作草案,针对样式表里反复出现的色值提出具名变量;当时写作 var-color,用 var(color) 引用,最终取值仍由层叠决定。
  • 2015 年 12 月 3 日的候选建议使用 --main-color 与 var(--main-color)。2022 年 6 月 16 日的候选建议快照细化了备用值、缺失引用与循环依赖。根部的颜色可以传给后代,局部组件也可以自己作主。

主编说,把网站的酒红色改得轻快一点。设计师打开样式表,发现旧色住在按钮、链接、提示框和一个三次改版都没搬走的标题里。改一处不难,难在别漏掉第四十处。漏掉的按钮像没收到通知的同事,依然穿着旧制服出席会议。CSS 变量给这场找人游戏换了规则:给颜色一个名字,让需要它的地方按名字取值。

W3C 于 2012 年 4 月 10 日公布的首份 CSS Variables 工作草案正是从重复数据的麻烦说起。大样式表会在许多位置重复颜色等数值,简单的查找替换可能把无关的相同字符也改了,或者漏掉散在别的文件里的副本。草案允许作者定义具名的变量属性,再在普通 CSS 属性中引用。例子把颜色放在文档根部,后代按照既有的层叠规则读取。它不是把文本从头到尾机械改写一遍,而是请浏览器按元素所在的位置投递。

最初的语法带着历史标签。草案写 var-color,引用时写 var(color)。同一份例子在根部给一个颜色,在 div 上换另一个,在警示元素上再换一次。名字相同,收件地址不同,颜色就能不同。总部的通知沿着树枝往下走,某个部门在自己的门口贴了新说明。变量真正有用的地方,正是它遵守层叠和局部范围,而不是只会喊一声“全站都改”。

有名字的属性还会出现办公室式推诿。一个变量说去问另一个,另一个又把问题推回来,就构成循环依赖。2012 年草案把这种关系描述为无效变量。浏览器不会在死胡同尽头发现一桶神秘颜料;它按计算值规则处理,引用这条链的声明要承担结果。命名减少了复制,也让依赖关系成为需要检查的东西。

到了2015 年 12 月 3 日的 W3C 候选建议,今天更熟悉的写法已经出现:定义 --main-color,使用 var(--main-color)。规范例子在根部设置主色,又让其他规则和一个派生的强调背景使用它。主色改变,依赖它的地方随之改变。编辑部不用再挨个拉开抽屉,确认每枚按钮是否拿到了新版色卡。

但投递路线仍由层叠掌管。局部组件若重新定义 --main-color,它的后代就会读到局部值。整站继续酒红,订阅面板可以改穿蓝绿。看到一枚颜色出乎意料的按钮,搜索到第一个同名声明只是线索;还要查它自身及祖先上哪个声明最终胜出。继承、选择器与局部覆盖决定了真正的收件人。颜色有名字,并不等于它住在一个全站通用的保险柜里。

W3C 于 2022 年 6 月 16 日发布的候选建议快照说明组件没收到通知时怎样体面出场。var(--header-color, blue) 的第二个参数提供备用值。一个可复用组件可以自带默认颜色,同时接受外部应用送来的新色。规范还说备用部分可以包含逗号,首个分隔逗号后面都属于备用值。客人带着自己的外套来,但主人借了一件合适的,也能穿。

缺失或循环引用的问题常在计算值阶段显形。浏览器读到含 var() 的声明时,未必已经知道替换进去的内容。等到替换,若名字没有有效值,也没有可用的备用值,依赖它的属性就得按无效声明的规则处理。设计师看见的实际颜色可能来自继承、局部覆盖、备用值,或者一条失效声明之后留下的结果。要查的是这枚按钮的计算后样式,而非搜索结果里第一行同名文字。

三份 W3C 文本也留下清楚的语法变迁。2012 年工作草案说 var-color 与 var(color);2015 年候选建议改用 --main-color 与 var(--main-color);2022 年候选建议快照把备用值与无效状态写得更细。不能把旧截图当作新样式表说明书。贯穿这些版本的办法倒很稳定:为值命名,让它顺着 CSS 的层叠与继承走,再允许局部支线回答自己的值。

编辑部因此可以讨论真正有意思的事:共享颜色该管到哪里?根部的酒红统一网站,警示框或嵌入组件可以有另一种色调,独立模块则在口袋里备一张备用色卡。浏览器负责送达与计算,编辑负责判断最后的页面是否还像同一家刊物。按钮们这回很难再辩称,通知从没发给自己。