堅定地使用CSS Custom Properties

堅定地使用CSS Custom Properties

好久沒譯文,最近看到這篇Getting Hardboiled with CSS Custom Properties 。覺得不錯,翻譯出來給大家。現在CSS新特性層出不窮,比如Flex,CSS Grid等等,我們是不是也可以按照這個思路使用,而不是藉助預處理工具呢?

廣告

自定義屬性(Custom Properties)是一個很有魅力的CSS 新特性,現代瀏覽器廣泛支持。但是遇到那些不支持CSS Custom Properties 的老掉牙瀏覽器我們該怎麼辦?等著這些瀏覽器死翹翹了再支持,還是使用預處理武裝CSS?又或者強硬起來,對它們一笑了之?

之前借助LESS 或者Sass 這樣預處理工具在樣式中使用變量,而今Custom Properties 在CSS 實現變量的原生支持。

如何使用自定義屬性?其實很簡單,在樣式規則錢添加--即可:

--color-text-default:black;

偏愛用下劃線?下面這樣也沒問題:

--color_text_default:black;

在屬性名稱中,橫線和下劃線都可以使用,作死使用空格是不行的。

自定義屬性名大小寫敏感, --color-text-default--Color-Text-Default是不一樣的哦。

使用var()函數可以獲取到自定屬性的值,這樣就可以在樣式規則中使用自定義屬性。如下例,瀏覽器獲取--color-text-default的值black ,應用到body元素上。

body{color:var(--color-text-default);}

與LESS 或者Sass 中的變量一樣,CSS Custom Properties 可以避免重複地在樣式表中編寫顏色、字體或者尺寸等樣式;不過除了這些CSS Custom Properties 還有更多的特點,級聯——可以根據平台的不同,通過media query 查詢來修改;更厲害的是, JavaScript 可以修改自定義屬性的值。

譯註: Custom Properties本質上是自定義屬性,即CSS屬性前面添加即是自定義屬性;借助CSS的var()函數,才可以使用這些自定義屬性。例如: var(--header-color) 。比起預處理器提供的變量特性,自定義屬性還有三個特點:層疊/級聯,運行時,JavaScript API。

Serg Hospodarets寫了一篇極好的文章介紹CSS Custom Properties ,範例詳盡,探索了各種可能用法。

瀏覽器支持

看到這裡你因該會問瀏覽器支持情況如何?那我們就來看看。最新版的Chrome、Edge、Firefox、Opera 和Safari 支持,IE 11 及以前、Opera Mini 情況不容樂觀。

總是這樣對不對?

不過別擔心,可以使用@support指令來檢查瀏覽器是否支持自定義屬性:

--color-text-default:black;body{color:black;}@supports((--foo:bar)){body{color:var(--color-text-default);}}

在Demo 中,一開始把body 文本顏色設置為黑色,後面如果瀏覽器支持我們偽造的foo 變量,則用一個自定義屬性值覆蓋之。

默認替代

如果使用的變量未定義會怎麼樣?沒有問題,瀏覽器會忽略這一條規則。如果你想確保萬無一失,可以使用替代指定一個備選值。

body{color:var(--color-text-default,black);}

替代與CSS 中的字體定義有點像,一個使用逗號隔開的列表。如果自定義屬性沒有值,瀏覽器忽略之使用列表中的下一個值。

譯註:原文這裡的說並不准確。 var( <custom-property-name> [, <declaration-value> ]? ) ,第一個逗號之後的內容都會被當作備選值。例如, var(--foo, red, blue) ,備選值是red, blue 。參考: CSS Custom Properties for Cascading Variables Module Level 1

預處理器

我們確實可以利用預處理器來把Custom Properties轉為兼容的CSS代碼,不過先打住,兄弟。

同樣的方式以前是不是也搞過?過去為了使用CSS3 的那些“高級”特性,比如border-radius、css columns、Flexbox 等等,我們工程師各種小技巧還少麼?問題確實解決了,只是代碼寫得噁心。

我想還有一種更好的方式——在支持的瀏覽器中盡情使用CSS Custom Properties ,為不支持的瀏覽器提供合適的稍有差別的體驗。怎麼地?之前我們也這麼幹過呀!

譯註:這種方式被稱作“漸進增強”,記得外刊君2012~13年試譯了《漸進增強的Web設計》 ,裡面有大量的漸進增強設計的技巧。翻譯了挺多章,但於翻譯質量被人民郵電出版社給bi了,:)。

兩種色調的Stuff & Nonsense

譯註:Stuff & Nonsense是原作者的站點。

在IE6臭名昭著的時代,我為我的站點提供了兩套設計

針對那個時代的現代瀏覽器,網站上到處都是新潮的各種顏色的箭頭和靶子。我使用了CSS 屬性選擇來實現,當年這可是高級特性:

[class="banner"]{background-colour:red;}

IE6會忽略那些無法解析的選擇器,因此,如果用戶用IE6訪問,會看到一個黑白為主)的站點,這些樣式我使用類選擇器實現的:

.banner{background-colour:black;}[class="banner"]{background-colour:red;}

不用說,我這樣做大家會覺得我腦子不正常,但是Microsoft 曾今使用我的網站作為IE7 支持屬性選擇器的參考。他們確實做了,就像我說的一樣:”做一個更好的瀏覽器吧!”。

過時瀏覽器,一邊呆著去

好了,這個例子和瀏覽器不支持CSS Custom Properties,有什麼關係?如何才能利用這些高級特性?不用擔心瀏覽器不支持,不用實現複雜的替代方案,不用花數個小時讓替代方案和設計保持一致。

答案就在於CSS 本身,而且一直如此,瀏覽器會直接忽略它們不認識的東西。

我們要做的很簡單,首先指定一個與設計大相徑庭的值,然後在再使用CSS 自定義屬性覆蓋之。

body{color:black;color:var(--color-text-default,black);}

所有瀏覽器都懂第一個值(black),如果瀏覽器足夠聰明,懂得第二個值( var(--color-text-default) ),就會覆蓋第一個值。過時瀏覽器不理解就會裝作看不到,沒效果。這沒有問題,更不會死人。

對所有的自定義屬性都做這樣的處理。為使用過時瀏覽器的用戶提供更簡單的替代設計到樣式中,就像我在Stuff & Nonsense 上做的一樣。

結論

我相信沒人願意看到網站變壞或者不被別人喜歡——我也不想這樣——但是沒必要要求在每個瀏覽器裡展示都一致。我們可以為使用過時瀏覽器的用提供一個設計相對簡單的替代方案。

做是否啟用新的CSS 特性的決定時,不要老往技術上考量,有時候可能需要改變一下對所有瀏覽器都要支持的態度。對老舊瀏覽器不要心慈手軟,接受CSS Custom Properties 帶來的紅利,堅定地用起來!

更多資源:

What do you think?

Written by marketer

首屆螞蟻金服體驗科技大會

福利! 30 張AI + 移動技術大會外刊專享票免費拿!