css 变量

 

css 变量(自定义属性)虽然已经发布很久了, 而且主流浏览器基本上已经都支持了, 但是工作中应用的仍然比较少, 但作为基础, 了解还是很有必要的。

用法

声明

类似编程语言一样, 要想使用变量需要先声明, 声明方式是使用 -- 开始, 然后后面跟变量名。 变量的声明要放在选择器中, 对当前选择器选中的元素生效, 如果要在所有选择器中生效, 那么则在 :root 中声明, 如下

:root {
  --primary-color: red;
}

变量声明对大小写敏感, --primary-color--Primary-Color 是两个不同的变量

使用

既然变量声明好了, 那我们就可以使用了, 使用的方式也很简单, 使用 var 函数包裹一个变量, 如下

p {
  color: var(--primary-color);
}

基本用法介绍完了, 一个声明, 一个使用, 是不是很简单呀?

注意点

css 变量的继承性

css 变量和 css 内置的属性一样, 只是没有默认的含义而已, 所以它也具有继承性

.one {
  --test: 20px;
}
.two {
  --test: 2em;
}
<div class='one'>
  <div class='two'></div>
  <div class='three'></div>
</div>

那么经过计算后

对于元素 class: one : 20px

对于元素 class: two : 2em

对于元素 class: three : 20px (继承自父属性)

自定义属性的默认值

var 函数还支持第二个参数, 表示变量的默认值, 如果该变量不存在, 就会使用这个默认值

.one {
  margin-top: var(--test, '20px');
}

.two {
  margin-top: var(--test, var(--test1, '20px')); /* 支持嵌套, 但是有性能问题 */
}

.three {
  margin-top: var(--test, --test1, '20px'); /* 无效 */
}

var 函数还可以用在变量的声明中

:root {
  --primary-color: red;
  --logo-text: var(--primary-color);
}

变量值只能用作属性值, 不能作为属性名

.foo {
  --side: margin-top;
  /* 无效 */
  var(--side): 20px;
}

变量值的类型

如果变量值是一个字符串, 可以与其他字符串拼接

--bar: 'hello';
--foo: var(--bar)' world';

如果变量值是数值, 不能与数值单位直接连用

.foo {
  --gap: 20;
  margin-top: var(--gap)px; /* 无效 */
}

上面代码中, 数值与单位直接写在一起, 这是无效的。 必须使用 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 是动态的,页面的任何变化,都会导致采用的规则变化。

利用这个特点,可以在响应式布局的media命令里面声明变量,使得不同的屏幕宽度有不同的变量值。

body {
  --primary: #7F583F;
  --secondary: #F7EFD2;
}

a {
  color: var(--primary);
  text-decoration-color: var(--secondary);
}

@media screen and (min-width: 768px) {
  body {
    --primary:  #F7EFD2;
    --secondary: #7F583F;
  }
}

兼容性处理

对于不支持 css 变量的浏览器, 可以使用下面的写法

a {
  color: red;
  color: var(--primary-color); /*如果支持css变量,下面的就会覆盖上面的,如果不支持,则使用上面的*/
}

也可以使用 @support 命令进行检测

@supports ( (--a: 0)) {
  /* supported */
}

@supports ( not (--a: 0)) {
  /* not supported */
}

javascript 操作

JavaScript 也可以检测浏览器是否支持 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');

这意味着,JavaScript 可以将任意值存入样式表。下面是一个监听事件的例子,事件信息被存入 CSS 变量。

const docStyle = document.documentElement.style;

document.addEventListener('mousemove', (e) => {
  docStyle.setProperty('--mouse-x', e.clientX);
  docStyle.setProperty('--mouse-y', e.clientY);
});

那些对 CSS 无用的信息,也可以放入 CSS 变量。

基于上面的使用方法,写了一个比较好玩的东西, 元素跟随鼠标移动

<!DOCTYPE html>
<html>
<head>
  <title>var test</title>
  <style type="text/css">
    #p {
      position: absolute;
      top: var(--mouse-y);
      left: var(--mouse-x);
      width: 20px;
      height: 20px;
      background-color: red;
    }
</style>
</head>
<body>
  <p id='p'></p>
  <script type="text/javascript">
    const docStyle = document.documentElement.style;

    document.addEventListener('mousemove', (e) => {
      console.log('mousemove')
        docStyle.setProperty('--mouse-x', e.clientX + 'px');
        docStyle.setProperty('--mouse-y', e.clientY + 'px');
    });
  </script>
</body>
</html>

天下文章一大抄啊!!! 哎

参考:

  1. 阮一峰 css 变量教程
  2. MDN 使用CSS自定义属性