堅定地使用 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;n
偏愛用下劃線?下面這樣也沒問題:
--color_text_default: black;n
在屬性名稱中,橫線和下劃線都可以使用,作死使用空格是不行的。
自定義屬性名大小寫敏感,--color-text-default
和 --Color-Text-Default
是不一樣的哦。
使用 var()
函數可以獲取到自定屬性的值,這樣就可以在樣式規則中使用自定義屬性。如下例,瀏覽器獲取 --color-text-default
的值 black
,應用到 body 元素上。
body {n color: var(--color-text-default);n}n
與 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;nnbody {n color: black;n}nn@supports((--foo: bar)) {n body {n color: var(--color-text-default);n }n}n
在 Demo 中,一開始把 body 文本顏色設置為黑色,後面如果瀏覽器支持我們偽造的 foo 變數,則用一個自定義屬性值覆蓋之。
默認替代
如果使用的變數未定義會怎麼樣?沒有問題,瀏覽器會忽略這一條規則。如果你想確保萬無一失,可以使用替代指定一個備選值。
body {n color: var(--color-text-default, black);n}n
替代與 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"] {n background-colour: red;n}n
IE6 會忽略那些無法解析的選擇器,因此,如果用戶用 IE6 訪問,會看到一個黑白為主)的站點,這些樣式我使用類選擇器實現的:
.banner {n background-colour: black;n}nn[class="banner"] {n background-colour: red;n}n
不用說,我這樣做大家會覺得我腦子不正常,但是 Microsoft 曾今使用我的網站作為 IE7 支持屬性選擇器的參考。他們確實做了,就像我說的一樣:」做一個更好的瀏覽器吧!」。
過時瀏覽器,一邊呆著去
好了,這個例子和瀏覽器不支持 CSS Custom Properties,有什麼關係?如何才能利用這些高級特性?不用擔心瀏覽器不支持,不用實現複雜的替代方案,不用花數個小時讓替代方案和設計保持一致。
答案就在於 CSS 本身,而且一直如此,瀏覽器會直接忽略它們不認識的東西。
我們要做的很簡單,首先指定一個與設計大相徑庭的值,然後在再使用 CSS 自定義屬性覆蓋之。
body{n color: black;n color:var(--color-text-default, black);n}n
所有瀏覽器都懂第一個值(black),如果瀏覽器足夠聰明,懂得 第二個值(var(--color-text-default)
),就會覆蓋第一個值。過時瀏覽器不理解就會裝作看不到,沒效果。這沒有問題,更不會死人。
對所有的自定義屬性都做這樣的處理。為使用過時瀏覽器的用戶提供更簡單的替代設計到樣式中,就像我在 Stuff & Nonsense 上做的一樣。
結論
我相信沒人願意看到網站變壞或者不被別人喜歡——我也不想這樣——但是沒必要要求在每個瀏覽器里展示都一致。我們可以為使用過時瀏覽器的用提供一個設計相對簡單的替代方案。
做是否啟用新的 CSS 特性的決定時,不要老往技術上考量,有時候可能需要改變一下對所有瀏覽器都要支持的態度。對老舊瀏覽器不要心慈手軟,接受 CSS Custom Properties 帶來的紅利,堅定地用起來!
更多資源:
- It』s Time To Start Using CSS Custom Properties—Smashing Magazine
- Using CSS variables correctly—Mike Riethmuller
- Developing Inspired Guides with CSS Custom Properties (variables)—Andy Clarke
推薦閱讀:
※ELSE 技術周刊(2017.11.20期)
※[譯文] 8pt柵格系統 - 2. 如何使用
※人見人愛的 Visual Studio Code
※十個免費的web前端開發工具
※面向對象實例--常用組件