在原生 css 中使用变量

定义

CSS变量,也称为CSS自定义属性。通过以--开头的自定义属性来设置变量名,存储一些特定值,在需要的地方使用 var() 来访问。如:

p {
  --primary-color: #6bc30d;
  color: var(--primary-color);
}

如何申明变量

可以像定义任何css属性一样来申明变量,不同的是,变量名必须以--开头。如 --primary-color: #6bc30d

如何使用变量

而要使用一个变量的值,需要使用 var() 函数,并将变量的名称作为参数传入。 如 color: var(--primary-color);

var()函数

var()函数可以代替元素中任何属性中的值的任何部分。

var() 函数接受两个参数,参数一是要替换的自定义属性的名称,参数二是可选的,作为参数一无效时候的回退值(如果第一个参数引用的自定义属性无效,则该函数将使用第二个值)。

var( <custom-property-name> [, <declaration-value> ]? )
/* <custom-property-name> 自定义属性名 */
/* <declaration-value> 声明值(回退值) */

使用变量的意义

  • 无需多次定义,同样的属性可以重复使用
  • 让CSS文件可读易维护(如主题样式,只需修改一个变量即可,而不再是枯燥的查找替换),灵活性更高

注意点

  • 变量名称必须以 -- 开头
  • 变量只能存储一个属性的值,而不能用来存储一个属性,如下例子是错误的:
    /* 这样是错误的 */
    p {
    --primary-color: color;
    var(--primary-color) : #6bc30d
    }
  • 变量中无法使用加减等数学方法,如果需要使用计算,则可以使用 calc 函数:
    /* 这样是错误的 */
    p {
    --font-size : 20px * 2;
    font-size: var(--font-size);
    }
    /* 这样是正确的 */
    p {
    --font-size : calc(20px * 2);
    font-size: var(--font-size); //40px
    }
    /* 这样拼接也是无效的 */
    p {
    --font-size: 20;
    font-size: var(--font-size)px; /* 无效 */
    }
    /* 这样是有效的: */
    p {
    --font-size: 20;
    font-size: calc(var(--font-size) * 1px); /* 20px */
    }
  • CSS变量是区分大小写的
    /* 这是两个不同的变量 */
    :root {
    --color: blue;
    --COLOR: red;
    }

scss等CSS预处理中变量的区别

  • CSS变量是浏览器原生支持的,不需要经过编译就可以使用
  • CSS变量是DOM的一部分,可以使用JS直接修改

作用域

虽然可以在css的任何地方定义变量,但是css变量也是有作用域的。CSS的变量作用域分为全局作用域和局部作用域。因此在申明一个变量之前,首先要确定这个变量要用在哪里?

全局变量

通过在:root中申明变量,就可以申明一个全局变量,可以在整个文档结构中使用这个变量,因为CSS变量是可继承的。

:root{
  --primay-color: #6bc30d;
}
/* 在任何地方都可以使用`:root`中定义的全局变量 */
p, div , a {
  color : var(--primay-color);
}
#myDiv, .myDiv {
  color : var(--primay-color);
}

局部变量

可以在除:root外的任何地方申明局部变量。但是局部变量只能够在被申明的元素及其子元素中使用。局部变量更多的应用在值覆盖上。

.modal {
  --modal-padding-top: 30px;
}
/* 当前元素及其子元素中使用 */
.modal, 
.modal-content {
  padding-top: var(--modal-padding-top); /* 30px */;
}
/* 在其他元素上无效 */
body {
  padding-top: var(--modal-padding-top); /* 无效设置,使用默认值 */
}

变量的继承

与其他CSS属性一样,CSS中的变量也是可以继承的。

:root{
  --color: red;
}
P {
  --pColor: green;
  color: var(--color); /* red */
}
p > span{
  color : var(-pColor); /* green */
}

https://img.smohan.net/500ab6df7212cda161ce27fd179db09d.png?imageView2/1/interlace/1/q/100![file](https://cdn.iluoy.com/uploads/articles/be1b12a566d3bfacdcf60533fb53c96d.png)

多个申明中变量的优先级

同名变量可以重复申明,这样变量就会有了优先级的问题,如下例子:

:root {
  --color: red;
}
div {
  --color: green;
}
#myDiv {
  --color: yellow; 
  --color: blue; 
}
* {
  color: var(--color);
}
<p>我正常显示红色</p>
<div>我显示绿色</div>
<div id="myDiv">
  我显示蓝色
  <p>那么我呢?</p>
</div>

https://img.smohan.net/61bb643203df1243edf0106d44ad9732.png?imageView2/1/interlace/1/q/100![file](https://cdn.iluoy.com/uploads/articles/96421c21e7fbba4b65e17c2464df9e75.png)

如图,div中的局部变量覆盖了:root中设置的值,而特定了ID的div元素#myDiv又覆盖了div中的值,最后作为#myDiv的子元素p继承了其父级的值,而不是使用root中申明的值

无效变量

对于变量来讲,CSS属性的有效性并不适用。对于变量这种自定义属性,即便在上下文环境中这个值是无意义的,但是都能够通过var()函数调用。无意义的变量值会导致无效的CSS申明。通过var()函数调用后会被解析为初始值。

:root {
  --color: 20px;
}
p {
  --font-size: green;
  background-color: var(--color); 
  /* background-color: 20px; 无效,将回退为transparent */
}

在html属性中使用css变量

就像其他CSS属性一样,在html中可以通过内联变量来设置变量的值,并且也能够正常工作

<style>
  p {
    color: var(--color);
  }
</style>
<body>
  <p style="--color:red; --font-size: 50px; font-size:var(--font-size);">
    我使用内联变量值得方式来设置样式
    <!-- 将显示为字号50px,颜色红色 -->
  </p>
</body>

在媒体查询中使用css变量

可以根据屏幕宽度的变化来改变变量的值,从而更容易的实现响应式布局。

:root {
  --font-size: 30px;
  --color: red;
}
html{
  color: var(--color);
  font-size: var(--font-size);
}

@media screen and (min-width: 480px) {
  :root {
    --font-size: 50px;
    --color: green;
  }
}
@media screen and (min-width: 760px) {
  :root {
    --font-size: 100px;
    --color: blue;
  }
}

https://img.smohan.net/e892604a409ac44ff0146b39d64849fb.gif?imageView2/1/interlace/1/q/100![file](https://cdn.iluoy.com/uploads/articles/bb0ae57c5c10fa1059cdb158ad860aa2.png)

在js中使用css变量

css变量是DOM的一部分,这意味着我们可以通过javascript来访问/修改css变量的值,这是scss等css预处理器所做不到的。 要用JavaScript来更新CSS变量,需要调用已声明变量元素上的style对象上的 setProperty 方法。

setProperty()

//语法
element.style.setProperty(propertyName, value, priority);
//propertyName 是一个 DOMString 被更改的CSS属性.
//value <可选> 是一个 DOMString 新的属性值. 如果没有指定, 则当作空字符.不能包含 "!important"
//priority <可选> 是一个 DOMString。允许 "important" CSS 优先被设置. 如果没有指定, 则当作空字符.

//在根元素(html)上更新变量值
document.documentElement.style.setProperty(propertyName, value)

示例

:root {
  --font-size: 20px;
  --background: red;
}
body {
  font-size: var(--font-size);
  background-color: var(--background);
  color: #fff;
}
<h1>使用JavaScript来改变背景色</h1>
 <button data-value="red">红色</button>
 <button data-value="green">绿色</button>
 <button data-value="blue">蓝色</button>
 <button data-value="yellow">黄色</button>

 <script>
   let $buttons = document.querySelectorAll('button')
   $buttons.forEach(button => {
     button.addEventListener('click', () => {
       let value = button.dataset.value
       document.documentElement.style.setProperty('--background', value)
     })
   })
 </script>

https://img.smohan.net/8b771ca9657331b75403227882b38745.gif?imageView2/1/interlace/1/q/100![file](https://cdn.iluoy.com/uploads/articles/0cb55b861617272ed41f2e8044ce7e38.png)

兼容性 file

原文链接:https://smohan.net/blog/w0incg