之前寫過了一篇關於自己對 css variable 的想法,原本對這個屬性沒有抱持著太大的期待,自己用習慣了 SASS 變數也覺得這個 css variable 反而像個彆腳的 system,不過如果你也是這樣想的人,可以參考這篇文章 Why should you care Css variables
css 的變數已經出來有一段期間了,瀏覽器的支援程度還不算太糟。或許各位都曾經想過,這些變數的功能在 SASS 上幾乎都做得到,而且搭配 SASS 的 function 以及 SASS 的型別(list map)變數的使用彈性更為強大。
不過這邊想要跟大家分享的是,css variable 真正亮眼的地方在哪裡。
這篇文章會假設大家已經有一些 css variable 的基礎。
附帶一提,這篇文章沒有很全面性的寫出如何使用 CSS variable,所以有任何建議都歡迎提出來,之後也會找時間來重新寫一篇比較全面性的文章。
支援度
Browser | Version |
---|---|
Chrome | 49 |
Firefox | 42 |
Safari | 9.1 |
custom property
只有在你讓他表現得像個 property 的時候,他才會比一般的預處理器強大
首先要澄清的一點是,在 CSS 的 spec 當中,variable 其實叫做 custom property
。這是什麼意思?變數跟 property 搞得我好混亂!
不要著急,意思就是在使用 css variable 的時候,我們應該把他們想成一般的 css 屬性使用,而非一般的變數而已。以下就會來介紹一些有關 css variable 的使用。
為什麼你要用 CSS Variable
- 你用這些屬性不需要一個預處理器。
- 可以用 initial inherit 的方式建立階層
- 瀏覽器會在需要的時候重新 render
- 你可以訪問並且用 JavaScript 操縱它們(等等會講到)
property 特性
既然是 css property 就一定會有以下幾個特性:
- 有所謂的
initial
inherit
的值可以使用 - 呼叫的方式是
var(--variable-name)
- 能夠放在
inline-style
裡面 - 可以用 js 取值、設值
其中,最大的亮點在於 inline-style 跟能夠與 js 搭配取值與設值。這是跟原本 SASS, LESS 等 CSS 預處理器最大的不同之處,也讓 CSS 具備了新的可能性,就讓我們來看一些範例吧!
:root {
--mainColor: #abc;
--subColor: #ccc;
}
h1 {
color: var(--mainColor);
}
在這邊 :root
所宣告的元素會繼承到所有的元素當中,這就是 custom property
的特性。
inline-style
因為是 property,所以當然可以像這樣寫。
<h1 style="color: var(--mainColor);">
Hello, world
</h1>
這看起來的確不怎麼稀奇,因為同樣的事情也可以用 class 跟 SCSS 變數的方式來達成,不過這讓我們在寫 inline style 的時候又多了一份可能性。
react inline style
例如在 react 當中,我們可能會需要寫一些 inline style,但是顏色的制定因為跳脫了 SCSS 的控制,常常顯得很彆扭,要嘛就是直接打上顏色碼,之後要修改的時候再捲起袖子慢慢改;或者用 js 另外保存一份顏色的變數表;最好的方法可能是幫每一個顏色變數賦予一個 class。
現在有了 css variable 我們可以很方便的使用。
const styles = {
heading: {
fontSize: "14px",
color: "var(--mainColor)",
},
warn: {
color: "var(--warnColor)",
},
}
const heading = ({ title }) => <h1 style={styles.heading}>{title}</h1>
本篇文章只聚焦在介紹 css variable,事實上也有其他優秀的 react style 管理方式
grid
設定 gutter,我們現在可以用 css variable 的方式來做到,也就是說,我們可以用 @media query
的方式來幫變數設值,這是一般預處理器做不到的事情,
js 的控制
透過 javascript 的操作,我們可以很輕鬆的幫 css 變數設值或取值,來達到 view 跟 js 分離的效果。例如我們有一些效果想要透過 js 來取值,並傳給 css。一般來說,我們可能會透過 javascript 做計算之後,再把計算後的值,用 inline style 呈現。
但這樣子有可能發生一些情形:
- 這個值可能不是我想要的,或是我也想要自己對值做一些操作。這樣一來就要重新修改 javascript 的程式碼,非常麻煩。
- 因為是用 inline style 設值,所以 CSS 無能為力。
有了 css variable 之後,設值、取值非常的方便。
取值
HTMLElement.style.getPropertyValue("--mainColor")
設值
HTMLElement.style.setProperty("--mainColor", "#abc")
所以,我們當然也可以套用事件註冊器,讓有興趣的數值注入到我們的變數之中。
const element = document.addEventListener("mousedown", e => {
// some HTMLElement;
element.style.setProperty("--pageX", e.pageX)
element.style.setProperty("--pageY", e.pageY)
})
支援度
如果要看看當前的瀏覽器是否有支援 CSS variable 的話,可以用 CSS.supports
的語法來檢測。
CSS.supports('(--css: variables)')
CSS.supports('not (--css: variables)')
之後的挑戰
因為管理變數的方式越來越多了,也有可能在 javascript 對變數進行設值的動作,所以在控制這些變數時我們應該要更小心一點。
- 變數的宣告統一處理:全域變數統一放在一個檔案或資料夾當中,之後會比較方便處理,如果是宣告 css variable 也一樣。
- 如果變數是為了讓 js 設值,可以試著加上前綴當作標記,例如:
--js-pageX
等等。
結論
這篇文章介紹了 CSS variable 使用方式與場景,之前我也覺得 css variable 很彆扭,不但寫起來醜不拉機,而且也沒有相對應的函數操作。
不過一旦理解 CSS variable 就是 custom property 的概念的時候,就會發現一些 CSS 以往無法突破的可能性。我們沒有必要一定要對 SASS 或是 CSS variable 做取捨,我們甚至可以將兩者搭配使用,做出一些以往無法達到的強大效果。