这篇文章需要技术复核。如何帮忙。
这是一个实验中的功能
此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。
CSS 变量是由网页的作者或用户定义的实体,用来指定文档中的特定变量。使用自定义属性来设置变量名,并使用特定的 var() 来访问。(比如 color:var(--main-color);)。
基本用法
声明一个变量:
element { --main-bg-color: brown; }
使用变量:
element { background-color: var(--main-bg-color); }
解决的问题
在构建大型站点时,作者通常会面对可维护性的挑战。在这些网页中, 所使用的 CSS 的数量是非常庞大的,并且在许多场合大量的信息会重复使用。例如,在网页中维护一个配色方案,意味着一些颜色在CSS文件中多次出现,并被重复使用。当你修改配色方案时,不论是调整某个颜色或完全修改整个配色,都会成为一个复杂的问题,不容出错,而单纯查找替换是远远不够的。
如果使用了 CSS 框架,这种情况会变得尤其糟糕,此时如果要修改颜色,则需要对框架本身进行修改。在这些场合使用 LESS 或 Sass 类似的预处理器是非常有帮助的,但是这种通过添加额外步骤的方式,可能会增加系统的复杂性。CSS变量为我们带来一些预处理器的便利,并且不需要额外的编译。
这些变量的第二个优势就是名称本身就包含了语义的信息。CSS 文件变得易读和理解。main-text-color比文档中的#00ff00更容易理解,特别是同样的颜色出现在不同的文件中的时候。
CSS变量能帮助我们干什么
在一些命令式编程语言中,像Java、C++亦或是JavaScript,通过变量我们能够跟踪某些状态。变量是一种符号,关联着一个特定的值,变量的值能随着时间的推移而改变。
在像CSS这种声明式语言中,随着时间而改变的值并不存在,也就没有所谓变量的概念了。
CSS 引入了一种层级变量的概念,从而能够从容应对可维护性的挑战。这就会使得在整个 CSS tree 中都可以象征性的引用一个变量。
什么是CSS变量
CSS 变量当前有两种形式:
- 变量,就是拥有合法标识符和合法的值。可以被使用在任意的地方。可以使用var()函数使用变量。例如:var(--example-variable)会返回--example-variable所对应的值
- 自定义属性。这些属性使用--*where*的特殊格式作为名字。例如--example-variable: 20px;即使一个css声明语句。意思是将20px赋值给--example-varibale变量。
自定义属性和常规属性一样,作用在当前的层级,若没有定义,则从其父元素继承其值。
开始使用CSS变量
让我们从这个简单的例子开始,拥有不同类名的元素有相同的颜色:
.one { color: white; background-color: brown; margin: 10px; width: 50px; height: 50px; display: inline-block; } .two { color: white; background-color: black; margin: 10px; width: 150px; height: 70px; display: inline-block; } .three { color: white; background-color: brown; margin: 10px; width: 75px; } .four { color: white; background-color: brown; margin: 10px; width: 100px; } .five { background-color: brown; }
把它应用到下面这段HTML:
<div> <div class="one"></div> <div class="two">Text <span class="five">- more text</span></div> <input class="three"> <textarea class="four">Lorem Ipsum</textarea> </div>
会得到下面的结果:
注意CSS中重复的地方,brown的背景色作用在不同的元素上面。我们可以将背景色定义在更高的层级,然后通过CSS继承解决这个问题。在某些情况下,这种方法不一定可行。定义一个变量在:root伪类上,使用变量来减少重复的代码。
:root { --main-bg-color: brown; } .one { color: white; background-color: var(--main-bg-color); margin: 10px; width: 50px; height: 50px; display: inline-block; } .two { color: white; background-color: black; margin: 10px; width: 150px; height: 70px; display: inline-block; } .three { color: white; background-color: var(--main-bg-color); margin: 10px; width: 75px; } .four { color: white; background-color: var(--main-bg-color); margin: 10px; width: 100px; } .five { background-color: var(--main-bg-color); }
只需要规范地声明所需的属性,就能得到和上面例子相同的结果
CSS变量的继承
自定义属性同样支持继承。一个元素上没有定义自定义属性,该自定义属性的值会继承其父元素:
<div class="one"> <div class="two"> <div class="three"> </div> <div class="four"> </div> <div> </div>
定义下面的CSS:
.two { --test: 10px; } .three { --test: 2em; }
在这个例子中,var(--test)的结果是:
class="two"
对应的节点:10px
class="three" 对应的节点
: element:2em
class="four"
对应的节点:10px
(inherited from its parent)class="one"
对应的节点: 无效值, 即此属性值为未被自定义css变量覆盖的默认值
有效性(validity)和值
在传统的CSS概念里,属性的有效性(validity)对于自定义属性来讲,并不适用。当自定义属性被解析,浏览器不知道哪里为调用到它们,所以几乎所有的值都是有效的。
不幸的是,这些有效值能通过var()函数操作符来调用,即使在当前上文没有意义。属性和自定义的值会导致无效的CSS声明,所有有了计算时有效(valid at computed time)的概念。
浏览器支持
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
Basic support | None | 29 (29) (disabled by default behind layout.css.variables.enabled option using old var-varname syntax)31 (31) (enabled by default) |
? | ? | ? |
Feature | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Basic support | ? | 29 (29) | ? | ? | ? |
[1] Chrome浏览器默认支持的值为添加-webkit-内核前缀的-webkit-var属性. 在-webkit-var()方法中无需定义前缀. 此外, 此功能隐藏于 chrome://flags
, 或称之为Enable experimental Web Platform features 开发者设置中的 Enable experimental WebKit features 选项。
[2] Chrome 34.0 y.因某些性能问题移除了此属性。
[3] 此功能在 layout.css.variables.enabled 之后发布
, 默认值为false
,Gecko 29默认支持较老的var-variablename 语法规则
. 自 Gecko 31 开始此功能被默认开启并启用--variablename
语法规则