在原生CSS中使用变量

本文首发于个人博客javascript

一直以来,CSS做为一种申明式的样式标记语言,很难像如javascript等命令式编程语言同样经过定义和使用变量的方式来维护和追踪某些状态。后来随着scss,less等CSS预处理器的出现,咱们能够像优秀的开源框架bootstrap那样,经过维护一个_variables.scss变量文件的方式来维护一个庞大的项目。但预处理须要编译,并不是CSS原生支持。而如今,咱们能够在原生CSS中使用变量了css

先来两个在线demo感觉一下:html

定义

CSS变量,也称为CSS自定义属性。经过以 --开头的自定义属性来设置变量名,存储一些特定值,在须要的地方使用 var() 来访问。如:
p {
  --primary-color: #6bc30d;
  color: var(--primary-color);
}

如何申明变量

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

如何使用变量

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

var()函数

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

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

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变量是可继承的。bootstrap

: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*/
}

css变量继承

多个申明中变量的优先级

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

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

变量优先级

如图,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;
  }
}

媒体查询改变变量值

在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>

使用JavaScript来改变背景色

参考文档

本文首发于个人博客

相关文章
相关标签/搜索