一、变量是个好东西
在任何语言中,变量的有一点作用都是一样的,那就是可以降低维护成本,附带还有更高性能,文件更高压缩率的好处。随着CSS预编译工具Sass/Less/Stylus的关注和逐渐流行,CSS工作组迅速跟进CSS变量的规范制定,并且,很多浏览器已经跟进,目前,在部分项目中已经可以直接使用了。
Chrome/Firefox/Safari浏览器都是绿油油的,兼容性大大超出我的预期,于是果断尝鲜记录下语法用法和特性。只可惜ie不兼容
二.CSS变量var()语法和用法和特性
CSS中原生的变量定义语法是:--*,变量使用语法是:var(--*),其中*表示我们的变量名称。关于命名这个东西,各种语言都有些显示,例如CSS选择器不能是数字开头,JS中的变量是不能直接数值的,但是,在CSS变量中,这些限制通通没有,例如: :root {
--1: #369;
}
span {
background-color: var(--1);
}
<span> --1:#369 </span>
但是,不能包含$,[,^,(,%等字符,普通字符局限在只要是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,但是可以是中文,日文或者韩文,例如:
span {
--红色: #f00;
background-color: var(--红色);
}
所以,我们就可以直接使用中文名称作为变量,即使英语4级没过的小伙伴也不会有压力了,我们也不需要随时挂个翻译器在身边了。
无论是变量的定义和使用只能在声明块{}里面,例如,下面这样是无效的:
--红色: #f00;
span {
background-color: var(--红色);
}
变量的定义,或者说声明跟CSS计数器的声明类似的,你应该摆脱Sass/Less等预编译工具语法先入为主的语法影响,把CSS的原生变量理解为一种CSS属性。
这样,你就对其权重和变量应用规则要容易理解地多。例如下面这个例子:
* { color: var(--color); }
:root { --color: purple; }
div { --color: green; }
#alert { --color: red; }
<p>我的紫色继承于根元素</p>
<div>我的绿色来自直接设置</div>
<div id='alert'>
ID选择器权重更高,因此阿拉是红色!
<p>我也是红色,占了继承的光</p>
</div>
上面这个例子我们可以获得这些信息:
1.变量也是跟着CSS选择器走的,如果变量所在的选择器和使用变量的元素没有交集,是没有效果的。例如#alert定义的变量,只有id为alert的元素才能享有。如果你想变量全局使用,则你可以设置在:root选择器上;
2.当存在多个同样名称的变量时候,变量的覆盖规则由CSS选择器的权重决定的,但并无!important这种用法,因为没有必要,!important设计初衷是干掉JS的style设置,但对于变量的定义则没有这样的需求。
(1).CSS属性名可以走变量吗?
类似下面这样:
span {
--bc: background-color;
var(--bc): #369;
}
//答案是“不可以”,要是可以支持的话,那CSS的压缩可就要逆天了,估计所有的属性都会变成1~2个字符。
(2).CSS变量支持同时多个声明吗? 不行
(3).CSS变量使用完整语法
CSS变量使用的完整语法为:var( [, ]? ),用中文表示就是:var( <自定义属性名> [, <默认值 ]? )如:background-color: var(--1, #f00);
(4).CSS变量不合法的缺省特性
span{
--color: 20px;
background-color: #369;
background-color: var(--color, #cd0000);
}
此时<span>的背景色是transparent。
对于 CSS变量,只要语法是正确的,就算变量里面的值是个乱七八糟的东西,也是会作为正常的声明解析,如果发现变量值是不合法的,例如上面背景色显然不能是20px,则使用背景色的缺省值,也就是默认值(transparent)代替,
(5).CSS变量的空格尾随特性
span{
--size: 20;
font-size: var(--size)px;
}
如果你以为是20px就太天真了,实际上,此处font-size:var(--size)px等同于font-size:20 px,注意,20后面有个空格,所以,这里的font-size使用的是<body>元素默认的大小。因此,就不要妄图取消就使用一个数值来贯穿全场.
/* 还是使用稳妥的做法*/
span{
--size: 30px;
font-size: var(--size);
}
/* 或者使用CSS3 calc()计算:*/
span {
--size: 30;
font-size: calc(var(--size) * 1px);
}
此时,<body>的font-size大小才是20px.
(6).CSS变量的相互传递特性
就是说,我们在CSS变量定义的时候可以直接引入其他变量给自己使用
body {
--green: #4CAF50;
--backgroundColor: var(--green);
}
或者更复杂的使用CSS3 calc()计算,例如:
body {
--columns: 4;
--margins: calc(24px / var(--columns));
}
对于复杂布局,CSS变量的这种相互传递和直接引用特性可以简化我们的代码和实现成本,尤其和动态布局在一起的时候,无论是CSS的响应式后者是JS驱动的布局变化。
CSS变量与响应式布局的例子:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
.box {
--columns: 4;
--margins: calc(24px / var(--columns));
--space: calc(4px * var(--columns));
--fontSize: calc((60 - 10*var(--columns)) * 1px);
}
.box {
width: 50%;
min-width: 320px;
margin: auto;
overflow: hidden;
}
.cell {
width: calc((100% - var(--margins) * var(--columns) * 2) / var(--columns));
margin: var(--margins);
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
background-color: #f0f3f9;
float: left;
height: 50px;
text-align: center;
font-size: var(--fontSize);
}
@media screen and (max-width: 1200px) {
.box {
--columns: 3;
}
}
@media screen and (max-width: 900px) {
.box {
--columns: 2;
}
}
@media screen and (max-width: 600px) {
.box {
--columns: 1;
}
}
</style>
</head>
<body>
<div class="box">
<div class="cell" style="color: #F44336;">box1</div>
<div class="cell" style="color: #E91E63;">box2</div>
<div class="cell" style="color: #9C27B0;">box3</div>
<div class="cell" style="color: #00BCD4;">box4</div>
<div class="cell" style="color: #009688;">box5</div>
<div class="cell" style="color: #4CAF50;">box6</div>
</div>
</body>
</html>
注意:calc();的算法。