瞭解CSS/CSS3原生變數var
一、變數是個好東西
在任何語言中,變數的有一點作用都是一樣的,那就是可以降低維護成本,附帶還有更高效能,檔案更高壓縮率的好處。
隨著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; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } <p>我的紫色繼承於根元素</p> <div>我的綠色來自直接設定</div> <div id='alert'> ID選擇器權重更高,因此阿拉是紅色! <p>我也是紅色,佔了繼承的光</p> </div>
上面這個例子我們可以獲得這些資訊:
- 變數也是跟著CSS選擇器走的,如果變數所在的選擇器和使用變數的元素沒有交集,是沒有效果的。例如#alert定義的變數,只有id為alert的元素才能享有。如果你想變數全域性使用,則你可以設定在:root選擇器上;
- 當存在多個同樣名稱的變數時候,變數的覆蓋規則由CSS選擇器的權重決定的,但並無!important這種用法,因為沒有必要,!important設計初衷是幹掉JS的style設定,但對於變數的定義則沒有這樣的需求。
CSS屬性名可以走變數嗎?
類似下面這樣:
body { --bc: background-color; var(--bc): #369; }
答案是“不可以”,要是可以支援的話,那CSS的壓縮可就要逆天了,估計所有的屬性都會變成1~2個字元。
CSS變數支援同時多個宣告嗎?
類似下面這樣:
…
不好意思,類似不了,語法上就根本不支援。
CSS變數使用完整語法
CSS變數使用的完整語法為: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之類的工具。
相關文章
- CSS變數var()語法和用法和特性CSS變數
- 在原生CSS中使用變數CSS變數
- CSS Var 自定義屬性中使用 Scss 變數CSS變數
- css3 漸變CSSS3
- css3漸變CSSS3
- 學習如何用CSS變數建立網頁響應佈局 — css var()CSS變數網頁
- CSS3 背景漸變CSSS3
- 在VsCode中幫你自動完成CSS變數的外掛:CSS Var CompleteVSCodeCSS變數
- css3中的@font-face你真的瞭解嗎CSSS3
- css3實現文字線性漸變,css3實現背景漸變CSSS3
- 用var宣告變數,在java中居然有這麼多細節,你都瞭解麼?變數Java
- css3有趣的transform形變CSSS3ORM
- css3背景顏色漸變CSSS3
- css3 | 淺談transform變換CSSS3ORM
- 1.變數:var,let,const變數
- 變數宣告帶var與不帶var的區別變數
- JavaScript變數宣告帶var與不帶var區別JavaScript變數
- 強大的CSS:var變數的區域性作用域(繼承)特性CSS變數繼承
- CSS3 之 3D 變換CSSS33D
- css3過渡詳解CSSS3
- 前端 let、const和var你真的瞭解麼?前端
- javascript動態改變css3的animationJavaScriptCSSS3
- 聊一聊CSS3的漸變——gradientCSSS3
- CSS3 radial-gradient()徑向漸變CSSS3
- CSS3 傾斜角度線性漸變CSSS3
- CSS3 linear-gradient() 線性漸變CSSS3
- 讓css3動畫變得有趣wowjsCSSS3動畫JS
- 你還在用var定義變數嗎?變數
- var與let宣告變數的區別變數
- var、let、const宣告變數的區別變數
- css3系列之詳解perspectiveCSSS3
- css3過渡效果詳解CSSS3
- CSS3對勾效果詳解CSSS3
- JavaScript全域性作用域下,變數加var和不加var的區別。JavaScript變數
- CSS3背景漸變效果程式碼例項CSSS3
- CSS3文字顏色漸變效果CSSS3
- CSS3漸變方式設定透明度CSSS3
- CSS3CSSS3
- CSS3 animation – steps 函式詳解CSSS3函式