在原生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來改變背景色

參考文檔

本文首發於個人博客

相關文章
相關標籤/搜索