CSS原生变量(CSS Variable)学习教程
前言
相信对于很多熟练使用Sass/Less/Stylus等CSS预编译器的程序员来说,使用CSS变量可以提高性能,降低维护成本,现在CSS也能原生使用这个属性了,真的是振奋人心,今天就让我们一起来了解下吧。
开始使用
- 
变量声明
 
声明变量的时候,变量名前面要加两根连词线(--),变量名大小写敏感:
:root{
    --color:red;
}
- 
变量读取
 
var(变量名,[默认值])函数用于读取变量,:
a {
  color: var(--color);
}
变量名不存在,就会使用这个默认值,注意第二个参数的默认值不处理内部的逗号或空格,都视作参数的一部分:
var(--font-stack, "Roboto", "Helvetica");
var(--pad, 10px 15px 20px);
注意,变量值只能用作属性值,不能用作属性名。
.foo {
  --side: margin-top;
  /* 无效 */
  var(--side): 20px;
}
- 
变量值的类型
 
如果变量值是一个字符串,可以与其他字符串拼接:
--bar: 'hello';
--foo: var(--bar)' world';
如果变量值是数值,不能与数值单位直接连用,必须使用calc()函数将之连接:
.foo {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}
如果变量值带有单位,就不能写成字符串。
/* 无效 */
.foo {
  --foo: '20px';
  font-size: var(--foo);
}
/* 有效 */
.foo {
  --foo: 20px;
  font-size: var(--foo);
}
- 
作用域
 
同一个 CSS 变量,可以在多个选择器内声明。读取的时候,优先级最高的声明生效,与 CSS 的"层叠"(cascade)规则是一致的。所以通常我们把全局的变量都放在根元素:root里面:
:root {
  --main-color: #06c;
}
- 
兼容性处理
 
可以使用@support命令进行检测。
@supports ( (--a: 0)) {
  /* supported */
}
@supports ( not (--a: 0)) {
  /* not supported */
}
- 
JS操作
 
使用JS判断是否支持CSS变量:
const isSupported =
  window.CSS &&
  window.CSS.supports &&
  window.CSS.supports('--a', 0);
if (isSupported) {
  /* supported */
} else {
  /* not supported */
}
JavaScript 操作 CSS 变量的写法如下。
// 设置变量
document.body.style.setProperty('--primary', '#7F583F');
// 读取变量
document.body.style.getPropertyValue('--primary').trim();
// '#7F583F'
// 删除变量
document.body.style.removeProperty('--primary');
- 
浏览器支持情况
 
CSS变量的用途
- 
响应式布局
 
我们可以在media里面声明变量,就可以使得不同的屏幕分辨率具有不同的CSS属性。
- 
代码更加符合 DRY(Don‘t repeat yourself)原则
 
可以定义一个变量一次,然后在页面多次使用。
- 
精简代码,减少冗余
 - 
方便的从 JS 中读/写,统一修改
 
预处理器的局限性
- 
预处理器变量不是实时的
 
预处理器局限性最常见的情况是Sass无法在媒体查询中定义变量或使用@extend
- 
预处理器变量不能级联
 
由于预处理器不在浏览器中运行并且无法看到标记,它们不能通过DOM元素限定作用域
- 
预处理器变量不继承
 - 
预处理器变量不可互操作