在任何語言中,變數的有一點作用都是一樣的,那就是可以降低維護成本,附帶還有更高效能,檔案更高壓縮率的好處。
隨著CSS預編譯工具Sass/Less/Stylus的關注和逐漸流行,CSS工作小組迅速跟進CSS變量的規範制定,並且,很多瀏覽器已經跟進,目前,在部分項目中已經可以直接使用了。
# Chrome/Firefox/Safari瀏覽器都是綠油油的,相容性大大超出我的預期,於是果斷嚐鮮記錄下語法用法和特性。
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>
上面這個例子我們可以得到這些資訊:
變數也是跟著CSS選擇器走的,如果變數所在的選擇器和使用變數的元素沒有交集,是沒有效果的。例如#alert定義的變量,只有id為alert的元素才能享有。如果你想變數全域使用,則你可以設定在:root選擇器上;
當存在多個同樣名稱的變數時候,變數的覆蓋規則由CSS選擇器的權重決定的,但並無!important這種用法,因為沒有必要,!important設計初衷是乾掉JS的style設置,但對於變量的定義則沒有這樣的需求。
類似下面這樣:
body { --bc: background-color; var(--bc): #369; }
答案是“不可以”,要是可以支援的話,那CSS的壓縮可就要逆天了,估計所有的屬性都會變成1~2個字元。
類似下面這樣:
# …
# 不好意思,類似不了,文法上就根本不支持。
CSS變數使用完整語法
# CSS變數使用的完整語法為:var(,用中文表示就是:var( <自訂屬性名稱> [, <預設值 ]? ),
意思是,如果我們使用的變數沒有定義(注意,僅限於沒有定義),則使用後面的值作為元素的屬性值。舉個例子:
.box { --1: #369; } body { background-color: var(--1, #cd0000); }
則此時的背景色是#cd0000:
請看下面這個範例:
body { --color: 20px; background-color: #369; background-color: var(--color, #cd0000); }
請問,此時
的背景色是?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預設值的使用僅限於變數未定義的情況,並不包括變數不合法。
請看下面這個範例:
body { --size: 20; font-size: var(--size)px; }
请问,此时
的font-size大小是多少?如果你以为是20px就太天真了,实际上,此处font-size:var(--size)px等同于font-size:20 px,注意,20后面有个空格,所以,这里的font-size使用的是
元素默认的大小。因此,就不要妄图取消就使用一个数值来贯穿全场,还是使用稳妥的做法:body { --size: 20px; font-size: var(--size); }
或者使用CSS3 calc()计算:
body { --size: 20; font-size: calc(var(--size) * 1px); }
此时,
的font-size大小才是20px,就是说,我们在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/CSS3原生變數var的詳細內容。更多資訊請關注PHP中文網其他相關文章!