CSS Variable Study

少女Melody發表於2018-07-26

CSS變數能幫助我們幹什麼

在一些指令式程式設計語言中,像Java、C++亦或是JavaScript,通過變數我們能夠跟蹤某些狀態。變數是一種符號,關聯著一個特定的值,變數的值能隨著時間的推移而改變。
在像CSS這種宣告式語言中,隨著時間而改變的值並不存在,也就沒有所謂變數的概念了。
CSS 引入了一種層級變數的概念,從而能夠從容應對可維護性的挑戰。這就會使得在整個 CSS tree 中都可以象徵性的引用一個變數

一、什麼是CSS變數

CSS 變數當前有兩種形式:

變數,就是擁有合法識別符號和合法的值。可以被使用在任意的地方。可以使用var()函式使用變數。例如:var(–example-variable)會返回–example-variable所對應的值
自定義屬性。這些屬性使用–where的特殊格式作為名字。例如–example-variable: 20px;即使一個css宣告語句。意思是將20px賦值給–example-varibale變數

二、變數的宣告

變數的命名

變數宣告使用兩根連詞線–表示變數,$color是屬於Sass的語法,@color是屬於Less的語法,為避免衝突css原生變數使用–)

注意: 變數名大小寫敏感,--header-color--Header-Color是兩個不同變數

宣告方式

CSS變數宣告的方式非常簡單,如下,宣告瞭一個名叫color的CSS變數。

  • 在css檔案中寫
  • 寫在html標籤的inline-style裡
  • 用JS給某個元素宣告,方法.style.setProperty
body{
  --color: red;
}
<body style="--color: red;"></body>
document.getElementsByTagName(`body`)[0].style.setProperty(`--color`, `red`)
變數值的型別

如果變數值是一個字串,可以與其他字串拼接

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


body:after {
  content: `--screen-category : `var(--screen-category);
}

如果變數值是數值,不能與數值單位直接連用,必須使用calc()函式,將它們連線

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

.foo {
  --gap: 20;
  margin-top: calc(var(--gap) * 1px);
}

如果變數值帶有單位,就不能寫成字串


/* 無效 */
.foo {
  --foo: `20px`;
  font-size: var(--foo);
}

/* 有效 */
.foo {
  --foo: 20px;
  font-size: var(--foo);

注意: 變數值只能用作屬性值,不能用作屬性名

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

上面程式碼中,變數–side用作屬性名,這是無效的

三、CSS變數的繼承&作用域

自定義屬性同樣支援繼承。一個元素上沒有定義自定義屬性,該自定義屬性的值會繼承其父元素

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” 對應的節點: element: 2em
  • class=”four” 對應的節點: 10px (inherited from its parent)
  • class=”one” 對應的節點: 無效值, 即此屬性值為未被自定義css變數覆蓋的預設值

最頂層的作用域就是:root

四、響應式

div {
  --color: #7F583F;
  --bg: #F7EFD2;
}

.mediabox {
  color: var(--color);
  background: var(--bg);
}

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

五、與前處理器的不同

1、前處理器變數不是實時的

$color:#7F583F;

@media screen and (min-width: 768px) {
    $color: #F7EFD2;
}

.mediabox {
      background: $color;
}

編譯結果

.mediabox {
  background: #7F583F; 
}

2、前處理器不能限定作用域

$zcolor:blue;
.ulbox {
    $zcolor:red;
}
ul{
    color: $zcolor;
}

編譯為

ul {
  color: blue; 
}

3、前處理器變數不可互操作

原生的CSS自定義屬性可以與任何CSS前處理器或純CSS檔案一起使用

六、JS操作變數

CSS 變數可以和 JS 互相互動

:root{
  --testMargin:70px;
}
//  讀取
var root = getComputedStyle(document.documentElement);
var cssVariable1 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable1); // `70px`
 
// 寫入
document.documentElement.style.setProperty(`--testMargin`, `100px`);
var cssVariable2 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable2);  // `100px`

// 刪除
document.documentElement.style.removeProperty(`--testMargin`);
var cssVariable3 = root.getPropertyValue(`--testMargin`).trim();
console.log(cssVariable3); // `70px`

七、相容性

檢測瀏覽器是否支援CSS自定義屬性的方法

/*css*/

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

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

if (window.CSS && window.CSS.supports && window.CSS.supports(`--a`, 0)) {
    alert(`CSS properties are supported`);
} else {
    alert(`CSS properties are NOT supported`);
}

https://caniuse.com/#search=c…

總結

相較於傳統的 LESS 、SASS 等前處理器變數,CSS 變數的優點在於:

  • CSS 變數的動態性,能在頁面執行時更改,而傳統前處理器變數編譯後無法更改
  • CSS 變數能夠繼承,能夠組合使用,具有作用域
  • 配合 Javascript 使用,可以方便的從 JS 中讀/寫

參考

CSS 變數教程
使用CSS變數
CSS變數和前處理器變數的差異

相關文章