CSS Variables (下一代 CSS )
CSS变量,也叫做CSS自定义属性。他们可用于减少CSS中的重复,以及强大的运行时效果,比如主题切换、多重填充等未来的CSS功能。
CSS的混乱
以往我们的应用里,为了保持外观的一致性,通常都会重复使用一些颜色,而每次更改一种颜色时,在不断的查找替换中很容易就引发错误。
直到LESS、SASS这样的CSS预处理器出现,让我们使用函数式编程的技巧来书写CSS,极大的提高了开发效率。但它们还是有一个主要的缺点,即它们是静态的,在运行时不能被更改。
自定义属性
我们来看一个简单的示例:
:root {
--mainColor: #ccc;
}
div {
color: var(--mainColor);
}
我们定义了一个--mainColor
的变量,然后使用var()
函数来使用这个变量。
语法
自定义属性的语法很简单:
--color: #fff;
使用两个破折号开头来定义一个变量,且区分大小写,所以--color
和--COLOR
是两个不同的变量。我们还可以这样用:
--foo: if(x > 5) this.width = 10;
虽然这样的写法在普通属性中是无效的,但它可以在运行时被Javascript读取并执行,这是预处理器所不能做到的。
级联
自定义属性遵循标准级联规则
/* CSS */
:root { --color: blue; }
div { --color: green; }
#red { --color: red; }
* { color: var(--color); }
<!-- HTML -->
<p>(蓝色)我从根元素那继承了蓝色</p>
<div>(绿色)我被设置成绿色</div>
<div id="red">
(红色)我被特别设置成红色
<p>(红色)我从父元素那继承了红色</p>
</div>
因此,我们可以使用自定义属性在媒体查询中做响应式设计
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
这是SASS不能做到的,因为它不能在媒体查询中定义变量。
var()函数
我们使用var()
函数来引用自定义属性
var(<custom-property-name> [, <declaration-value> ]? )
<custom-property-name>
是使用者定义的自定义属性名,<declaration-value>
代表自定义属性名无效时的替代项(替代项会覆盖继承自父元素的样式),传递多个替代项时,以最后一个替代项为准。
/* CSS */
div {
--color: green;
}
.component .header {
color: var(--header-color, blue);
}
.component .text {
color: var(--text-color, black);
}
.component {
--text-color: #080;
}
<!-- HTML -->
<div class="component">
<p class="header">this is header</p>
<p class="text">this is text</p>
</div>
用calc()构建值
可以使用calc()
函数来动态生成值
.foo {
--gap: 20;
margin-top: calc(var(--gap) * 1px);
}
在JavaScript中使用自定义属性
现有一段自定义属性如下:
/* CSS */
:root {
--mainColor: orange;
}
p {
color: var(--mainColor);
}
<p>this is orange</p>
使用getPropertyValue()
方法可以获取到自定义属性的值。
var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--mainColor')).trim();
// value = 'orange'
也可以使用setProperty()
设置该对象的值
document.documentElement.style.setProperty('--mainColor', 'green');
还可以设置成一个var()调用中的函数,在运行时调用另一个自定义属性
document.documentElement.style.setProperty('--mainColor', 'var(--secondaryColor)');
浏览器支持
目前Chrome 49,Firefox 42,Safari 9.1和iOS Safari 9.3支持自定义属性。
对于不兼容的浏览器,也有相应的解决方案,postcss 提供了一个插件 cssnext 可以把下一代的CSS转化为目前通用的CSS。