CSS基礎篇--CSS/CSS3中的原生變量var詳解

使用語法

首先咱們先來看一個例子:
html代碼:css

<div class="element">這是一段文字</div>

css代碼:html

.element {
  width:200px;
  height:200px;
  --main-bg-color: #000;
  color:#fff;
  background-color: var(--main-bg-color);
}

實現效果:
圖片描述css3

結果是該DOM元素背景變成了黑色。瀏覽器

CSS中原生的變量定義語法是:--*,變量使用語法是:var(--*),其中*表示咱們的變量名稱。關於命名這個東西,各類語言都有些顯示,例如CSS選擇器不能是數字開頭,JS中的變量是不能直接數值的,可是,在CSS變量中,這些限制統統沒有,例如:wordpress

:root{
    --main-bg-color: #000;
}
.element {
    background-color: var(--main-bg-color);
}

注意:變量名稱不能包含$,[,^,(,%等字符,普通字符侷限在只要是「數字[0-9]」「字母[a-zA-Z]」「下劃線_」和「短橫線-」這些組合,可是能夠是中文,日文或者韓文,例如:函數

.element {
  width:200px;
  height:200px;
  --黑色: #000;
  color:#fff;
  background-color: var(--黑色);
}

css變量完整語法:
CSS變量使用的完整語法爲:var( [, ]? ),用中文表示就是:var( <自定義屬性名> [, <默認值 ]? ),也便是若是咱們沒有定義變量名稱,那麼就會使用後面的值做爲其默認屬性值。
以下:工具

.element {
    background-color: var(--new-bg-color,#EE0000);
}

獲得的結果固然是後面顏色的值的背景。網站

咱們來看一下若是變量名稱不合法會出現什麼結果,看下面例子:spa

body {
  --color: 20px;
  background-color: #369;
  background-color: var(--color, #cd0000);
}

請問,此時<body>的背景色是?3d

  • A. transparent
  • B. 20px
  • C. #369
  • D. #cd0000

答案是:A. transparent
CSS變量中,果發現變量值是不合法的,例如上面背景色顯然不能是20px,則使用背景色的缺省值,也就是默認值代替,因而,上面CSS等同於:

body {
    --color: 20px;
    background-color: #369;
    background-color: transparent;
}

css變量在js中的應用

看以下例子,html代碼:

<div id="jsDom">這是一段文字</div>

css代碼:

#jsDom {
    --my-varwidth: 200px;
    background-color: #000;
    color:#fff;
    width:var(--my-varwidth);
    height:200px;
}

js代碼:

var element = document.getElementById('jsDom');
var curWidth = getComputedStyle(element).getPropertyValue("--my-varwidth");
console.log(curWidth); //200px

//設置事後該DOM元素的寬度變爲了300px
element.style.setProperty("--my-varwidth", '300px');

若是樣式是寫到行間呢?那麼進行以下操做:
html代碼:

<div id="jsDom" style="--my-varwidth:400px;width:var(--my-varwidth);">這是一段文字</div>

js代碼:

var element = document.getElementById('jsDom');
var curWidth = element.style.getPropertyValue("--my-varwidth");
console.log(curWidth); //400px

瀏覽器兼容

瀏覽器的兼容如圖所示:
圖片描述

到目前位置IE11也不支持該css變量。

說到這兒感受這個css變量也是很強大的,那麼它跟預處理器比較,你以爲哪一個更好?下面講一下預處理器的劣勢。

預處理器劣勢

預處理器變量不是實時的

也許令新手驚訝的是,預處理器侷限性最多見的狀況是Sass沒法在媒體查詢中定義變量或使用@extend。

$gutter: 1em;
@media (min-width: 30em) {
     $gutter: 2em; 
} 
 .Container { 
     padding: $gutter; 
 }

上面代碼將編譯爲:

.Container { 
     padding: 1em;
 }

上面結果能夠看出來,媒體查詢塊被丟棄,變量賦值被忽略。

因爲沒法在匹配@media規則的基礎上改變變量,因此惟一的選擇是爲每一個媒體查詢分配一個惟一的變量,並單獨編寫每一個變體。

預處理器變量不能級聯

每當使用變量,做用域的問題就不可避免的出現。這個變量應該設置爲全局變量嗎?是否應該限定其範圍爲文件或模塊?是否應該限制在塊中?

因爲CSS最終目的是爲HTML添加樣式,事實證實還有另外一種有效的方法給變量限定做用域:DOM元素。但因爲預處理器不在瀏覽器中運行而且沒法看到標記,它們不能這樣作。

假設有一個網站,面對偏好較大文字的用戶,就向<html>元素添加類user-setting-large-text。當設置了這個類時,應當應用較大的$font-size變量賦值:

$font-size: 1em;
.user-setting-large-text {
    $font-size: 1.5em;
} 
body { 
    font-size: $font-size; 
}

但一樣,就像上面的媒體塊示例,Sass徹底忽略了該變量的賦值,這意味着這是不可能發生的。編譯後的代碼以下:

body { 
    font-size: 1em;
}

預處理器變量不繼承

雖然繼承嚴格說來是級聯的一部分,之因此把它單獨分出來說,是由於屢次想調用這個特性卻不得。

假設一種狀況,要在DOM元素上基於其父元素應用的顏色而設置樣式:

.alert {
    background-color: lightyellow;
}
.alert.info {
    background-color: lightblue;
}
.alert.error {
    background-color: orangered;
}

.alert button {
    border-color: darken(background-color, 25%);
}

上面的代碼並非有效的Sass(或CSS),但你應該明白它想達到什麼目的。

最後一句聲明試圖在<button>元素從父元素.alert元素繼承的background-color屬性使用Sassdarken函數。若是類infoerror已經加在了.alert上(或若是background-color已經過JavaScript或用戶樣式設置),button元素能據此做出相應的響應。

顯然這在Sass中行不通,由於預處理器不知道DOM結構,但但願你清楚的認識到爲何這類東西是有用的。

調用一個特定的用例:出於可訪問性的緣由,在繼承了DOM屬性上運行顏色函數是極其方便的。例如,確保文本始終可讀,並充分與背景顏色造成鮮明對比。 有了自定義屬性和新的CSS顏色函數,很快這將成爲可能。

預處理器變量不可互操做

這是預處理器相對明顯的一個缺點,提到它是由於我以爲它重要。若是你正使用PostCSS來構建網站,想使用只能經過Sass實現主題化的第三方組件,那你真是不走運了。

跨不一樣的工具集或CDN上託管的第三方樣式表共享預處理器變量是不可能(或至少不容易)的。

原生的CSS自定義屬性能夠與任何CSS預處理器或純CSS文件一塊兒使用。反之則否則。

下面給一個css變量在媒體查詢中的使用:

:root {
    --gutter: 1.5em;
}

@media (min-width: 30em) {
    :root {
        --gutter: 2em;
    }
}
@media (min-width: 48em) {
    :root {
        --gutter: 3em;
    }
}

若是是預處理器這樣寫就無效了。

參考

Using CSS custom properties (variables)
小tips:瞭解CSS/CSS3原生變量var
我爲何對原生CSS變量感到興奮

相關文章
相關標籤/搜索