前言

相信对于很多熟练使用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元素限定作用域

  • 预处理器变量不继承

  • 预处理器变量不可互操作

参考链接