瞭解CSS/CSS3原生變量var

1、變量是個好東西

在任何語言中,變量的有一點做用都是同樣的,那就是能夠下降維護成本,附帶還有更高性能,文件更高壓縮率的好處。瀏覽器

隨着CSS預編譯工具Sass/Less/Stylus的關注和逐漸流行,CSS工做組迅速跟進CSS變量的規範制定,而且,不少瀏覽器已經跟進,目前,在部分項目中已經能夠直接使用了。工具

CSS變量var兼容性截圖

Chrome/Firefox/Safari瀏覽器都是綠油油的,兼容性大大超出個人預期,因而果斷嚐鮮記錄下語法用法和特性。佈局

2、CSS變量var()語法和用法和特性

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

:root {
  --1: #369;
}
body {
  background-color: var(--1);
}

結果背景色以下:
變量背景色示意測試

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

body {
  --深藍: #369;
  background-color: var(--深藍);
}

因此,咱們就能夠直接使用中文名稱做爲變量,即便英語4級沒過的小夥伴也不會有壓力了,咱們也不須要隨時掛個翻譯器在身邊了。翻譯

不管是變量的定義和使用只能在聲明塊{}裏面,例如,下面這樣是無效的:設計

--深藍: #369;
body {
  background-color: var(--深藍);
}

變量的定義,或者說聲明跟CSS計數器的聲明相似的,你應該擺脫Sass/Less等預編譯工具語法先入爲主的語法影響,把CSS的原生變量理解爲一種CSS屬性。code

這樣,你就對其權重和變量應用規則要容易理解地多。blog

例以下面這個例子:

:root { --color: purple; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } <p>個人紫色繼承於根元素</p> <div>個人綠色來自直接設置</div> <div id='alert'> ID選擇器權重更高,所以阿拉是紅色! <p>我也是紅色,佔了繼承的光</p> </div> 

上面這個例子咱們能夠得到這些信息:

  1. 變量也是跟着CSS選擇器走的,若是變量所在的選擇器和使用變量的元素沒有交集,是沒有效果的。例如#alert定義的變量,只有idalert的元素才能享有。若是你想變量全局使用,則你能夠設置在:root選擇器上;
  2. 當存在多個一樣名稱的變量時候,變量的覆蓋規則由CSS選擇器的權重決定的,但並沒有!important這種用法,由於沒有必要,!important設計初衷是幹掉JS的style設置,但對於變量的定義則沒有這樣的需求。

CSS屬性名能夠走變量嗎?

相似下面這樣:

body {
    --bc: background-color;    
    var(--bc): #369;
}

答案是「不能夠」,要是能夠支持的話,那CSS的壓縮可就要逆天了,估計全部的屬性都會變成1~2個字符。

CSS變量支持同時多個聲明嗎?

相似下面這樣:

很差意思,相似不了,語法上就根本不支持。

CSS變量使用完整語法
CSS變量使用的完整語法爲:var( [, ]? ),用中文表示就是:var( <自定義屬性名> [, <默認值 ]? )

意思就是,若是咱們使用的變量沒有定義(注意,僅限於沒有定義),則使用後面的值做爲元素的屬性值。舉個例子:

.box {
  --1: #369;
}
body {
  background-color: var(--1, #cd0000);
}

則此時的背景色是#cd0000
紅色背景色

CSS變量不合法的缺省特性

請看下面這個例子:

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

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

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

答案是…………………………A. transparent

不知你們答對了沒有!

這是CSS變量很是有意思的一個點,對於CSS變量,只要語法是正確的,就算變量裏面的值是個亂七八糟的東西,也是會做爲正常的聲明解析,若是發現變量值是不合法的,例如上面背景色顯然不能是20px,則使用背景色的缺省值,也就是默認值代替,因而,上面CSS等同於:
body {
--color: 20px;
background-color: #369;
background-color: transparent;
}

千萬不能想固然得認爲等同於background-color:20px,這也是爲何上面要強調CSS默認值的使用僅限於變量未定義的狀況,並不包括變量不合法。

CSS變量的空格尾隨特性    更多問題CSS/CSS3繼續閱讀

請看下面這個例子:

body {
  --size: 20;   
  font-size: var(--size)px;
}

請問,此時<body>font-size大小是多少?

若是你覺得是20px就太天真了,實際上,此處font-size:var(--size)px等同於font-size:20 px,注意,20後面有個空格,因此,這裏的font-size使用的是<body>元素默認的大小。所以,就不要妄圖取消就使用一個數值來貫穿全場,仍是使用穩妥的作法:

body {
  --size: 20px;   
  font-size: var(--size);
}

或者使用CSS3 calc()計算:

body {
  --size: 20;   
  font-size: calc(var(--size) * 1px);
}

此時,<body>font-size大小纔是20px

CSS變量的相互傳遞特性

就是說,咱們在CSS變量定義的時候能夠直接引入其餘變量給本身使用,例如:

body {
  --green: #4CAF50;   
  --backgroundColor: var(--green);
}

或者更復雜的使用CSS3 calc()計算,例如:

body {
  --columns: 4;
  --margins: calc(24px / var(--columns));
}

對於複雜佈局,CSS變量的這種相互傳遞和直接引用特性能夠簡化咱們的代碼和實現成本,尤爲和動態佈局在一塊兒的時候,不管是CSS的響應式後者是JS驅動的佈局變化。

咱們來看一個CSS變量與響應式佈局的例子,您能夠狠狠地點擊這裏:CSS變量與響應式佈局實例demo

默認進去是4欄,以下圖:

隨着瀏覽器寬度減少,4欄可能就變成3欄,2欄甚至1欄,咱們實際開發的時候,顯然不只僅是欄目數量變化,寬度小,每每意味着訪問設備尺寸有限,此時咱們每每會縮小空白間距以及文字字號大小,這樣,有限屏幕才能顯示更多內容。

也就是說,當咱們響應式變化的時候,改變的CSS屬性值不是1個,而是3個或者更多,若是咱們有3個響應點,是否是就至少須要9個CSS聲明?可是,因爲咱們有了CSS變量,同時,CSS變量能夠傳遞,當咱們遭遇響應點的時候,咱們只須要改變一個CSS屬性值就能夠了。

下面就是本demo核心CSS代碼(只須要改變--columns這一個變量便可):

.box {
    --columns: 4;
    --margins: calc(24px / var(--columns));
    --space: calc(4px * var(--columns));
    --fontSize: calc(20px - 4 / var(--columns));
}
@media screen and (max-width: 1200px) {
    .box {
        --columns: 3;
    }
}
@media screen and (max-width: 900px) {
    .box {
        --columns: 2;
    }
}
@media screen and (max-width: 600px) {
    .box {
        --columns: 1;
    }
}

因而,咱們在2欄下的效果就是這樣,字號,間距隨着欄目數量的減少也一併減少了,而後每欄之間間距是擴大了:

有沒有以爲CSS愈來愈屌了呢!哈哈~

3、結束語

因爲目前幾乎沒有關於CSS3 var()的文章,所以,上面關於var()的語法特性等都是本身經過看規範文檔,外加細緻的測試獲得的。可是,一我的的能力老是有限的,所以,必然還有不少var()變量有意思的點沒發現,所以,就但願你們如果發現var()其餘有意思的地方,歡迎評論告知,咱們及時添加在文章中,方便你我他她它。

相關文章
相關標籤/搜索