CSS 自定义属性(变量)

一、概念

自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如:--main-color: black;),由var()函数来获取值(比如: color: var(--main-color);)。
大量的CSS代码,通常也会有许多重复的值。例如,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,--main-text-color会比 #00ff00 更易理解,尤其是这个颜色值在其他上下文中也被使用到。自定义属性受级联的约束,并从其父级继承其值。

二、基础用法

声明一个自定义属性,属性名需要以两个减号(--)开始,属性值则可以是任何有效的CSS值。和其他属性一样,自定义属性也是写在规则集之内的,如下:

element {
  --main-bg-color: brown;
}

如上若是,element表示该变量的规则集(作用域集),可以是某个具体的类名或者id等选择器。
使用一个局部变量时用var()函数包裹以表示一个合法的属性值,引用该变量值,如下:

element {
  background-color: var(--main-bg-color);
}

三、规则集作用域

element规则集作用域范围仅用于匹配当前选择器及其子孙,这和通常的CSS是一样的。如下:

<div class="one">
  <div class="two">
    <div class="three"></div>
    <div class="four"></div>
  </div>
</div>

配套CSS

.two {
  --test: 10px;
}

.three {
  --test: 2em;
}

在这个情况下, var(--test) 的结果分别是:

  • 对于元素class="two" 10px
  • 对于元素class="three"2em
  • 对于元素class="four"10px (继承自父属性)
  • 对于元素class="one" :非法值,会变成自定义属性的默认值
    所以,通常的最佳实践是定义在根伪类:root下,这样就可以在HTML文档的任何地方均可访问,如下:
:root {
  --main-bg-color: brown;
}

当然这条规则不是绝对的,如果有理由去限制你的自定义属性,那么就应该限制。此外,自定义属性名是大小写敏感的,--my-color--My-color会被认为是两个不同的自定义属性。

四、自定义属性备用值

var()函数可以定义多个备用值(fallback value),当给定值未定义时将会用备用值替换。
备用值并不是用于实现浏览器兼容性的。如果浏览器不支持CSS自定义属性,备用值也没什么用。它仅对支持CSS自定义属性的浏览器提供了一个备份机制,该机制仅当给定值未定义或是无效值的时候生效。
函数的第一个参数是自定义属性的名称。如果提供了第二个参数,则表示备用值,当自定义属性值无效时生效。第二个参数可以嵌套,但是不能继续平铺展开下去了,例如:

.two {
  color: var(--my-var, red); /* 如果--my-var未定义或者无效,则使用red */
}

.three {
  background-color: var(--my-var, var(--my-background, pink)); /* pink if --my-var and --my-background are not defined */
}

.three {
  background-color: var(--my-var, --my-background, pink); /* Invalid: "--my-background, pink" */
}

注意:第二个例子展示了如何处理一个以上的 fallback。该技术可能会导致性能问题,因为它花了更多的时间在处理这些变量上。

五、自定义属性的有效性和值

传统的 CSS 概念里,有效性和属性是绑定的,例如,如果对某个颜色属性赋予了长度值,则css会有错误提示,例如color:16px,是不允许的,也是无意义的。但这对自定义属性来说并不适用,当自定义属性值被解析,浏览器不知道它们什么时候会被使用,所以必须认为这些值都是有效的。
除此,即便这些值是有效的,但当通过 var() 函数调用时,它在特定上下文环境下也可能不会奏效。
当浏览器遇到无效的 var() 时,会使用继承值或初始值代替。如下。
无效自定义属性

如上所示,浏览器将--text-color的值替换给了var(--text-color),但是16px并不是color的合法属性值。代换之后,该属性不会产生任何作用。浏览器会执行如下两个步骤:

  • 检查属性color是否为继承属性。是,但是<p>没有任何父元素定义了color属性。转到下一步。
  • 将该值设置为它的默认初始值,比如black
    段落颜色并不是蓝色,因为无效代换导致了它被替换成了默认初始值的黑色。如果你直接写color: 16px 的话,则会导致语法错误,而前面的定义则会生效(段落显示为蓝色)。
    备注:当 CSS 属性 - 值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。

六、JavaScript获取或设置自定义变量

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    :root {
      --text-color: 16px;
    }
    .clr {
      color: blue;
      color: var(--text-color);
      --my-var: yellow;
    }
  </style>
</head>
<body>
  <p id="pg" class="clr">This paragraph is initial black.</p>

  <script>
    let bodyObj = document.body;
    let pObj = document.getElementById('pg');
    // 获取自定义属性值
    let rootVar = getComputedStyle(bodyObj).getPropertyValue("--text-color");
    let myVar = getComputedStyle(pObj).getPropertyValue("--my-var");
    console.log(rootVar, myVar);

    // 修改自定义属性值
    bodyObj.style.setProperty("--text-color","red");
    console.log(getComputedStyle(bodyObj).getPropertyValue("--text-color"));
  </script>
</body>
</html>

运行结果:
运行结果

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值