瞭解CSS/CSS3原生變數var

來源:互聯網
上載者:User

  一、變數是個好東西

  在任何語言中,變數的有一點作用都是一樣的,那就是可以降低維護成本,附帶還有更高效能,檔案更高壓縮率的好處。

  隨著CSS先行編譯工具Sass/Less/Stylus的關注和逐漸流行,CSS工作群組迅速跟進CSS變數的規範制定,並且,很多瀏覽器已經跟進,目前,在部分項目中已經可以直接使用了。

  Chrome/Firefox/Safari瀏覽器都是綠油油的,相容性大大超出我的預期,於是果斷嘗鮮記錄下文法用法和特性。

  二、CSS變數var()文法和用法和特性

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

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

  結果背景色如下:

  但是,不能包含$,[,^,(,%等字元,一般字元局限在只要是“數字[0-9]”“字母[a-zA-Z]”“底線_”和“虛線-”這些組合,但是可以是中文,日文或者韓文,例如:

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

  所以,我們就可以直接使用中文名稱作為變數,即使英語4級沒過的小夥伴也不會有壓力了,我們也不需要隨時掛個翻譯器在身邊了。

  無論是變數的定義和使用只能在聲明塊{}裡面,例如,下面這樣是無效的:

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

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

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

  例如下面這個例子:

:root { --color: purple; }p { --color: green; }#alert { --color: red; }* { color: var(--color); }<p>我的紫色繼承於根項目</p><p>我的綠色來自直接設定</p><p id='alert'>  ID選取器權重更高,因此阿拉是紅色!  <p>我也是紅色,佔了繼承的光</p></p>

  上面這個例子我們可以獲得這些資訊:

  1. 變數也是跟著CSS選取器走的,如果變數所在的選取器和使用變數的元素沒有交集,是沒有效果的。例如#alert定義的變數,只有id為alert的元素才能享有。如果你想變數全域使用,則你可以設定在: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變數的空格尾隨特性

  請看下面這個例子:

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越來越屌了呢!哈哈~

  三、結束語

  由於目前幾乎沒有關於CSS3 var()的文章,因此,上面關於var()的文法特性等都是自己通過看規範文檔,外加細緻的測試得到的。但是,一個人的能力總是有限的,因此,必然還有很多var()變數有意思的點沒發現,因此,就希望大家若是發現var()其他有意思的地方,歡迎評論告知,我們及時添加在文章中,方便你我他她它。

  多人合作項目我也會使用Less/Sass之類的先行編譯工具,但是,基本上用到的就是變數,其他進階功能,幾乎都不怎麼使用。所以,如果瀏覽器全方位支援了原生的CSS變數,我十有八九就會拋棄Less/Sass之類的工具。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.