原生 CSS 變數運用技巧(CSS Variables)
Hi 大家好,我是卡斯伯。
這次要跟大家來介紹 CSS 的變數功能,在過去如果要在樣式表中使用變數功能,就會仰賴 Sass、Less 這樣的 CSS 預處理器,因為 CSS 本身是屬於靜態的樣式表,所以傳統上是沒有辦法做到這樣的特性,就只能透過編譯來達到。而現在 CSS 加入了變數功能,也因為此新功能是在原本的樣式表上做加強,所以看起來結構會有些「奇特」!?
為何樣式表需要變數呢?無論是使用 Sass 做編譯或是現在直接使用 CSS 變數有什麼好處呢?
- 統一整個樣式表的樣式:你的紅不代表我的紅。開發的過程中一定會有許多色彩、尺寸是不斷的重複使用,因此原始碼中就可能會產生許多類似但卻不相同的數值,在管理上以及視覺的統一就會有很大的問題。
- 基於預定的數值做計算:當有了基準數值後,變數還能基於這些值做計算,如上述的更深一點的紅、兩倍的距離等等;調整變數的同時也不需要一一的取代,這些數值都會依據變數直接套用。
以上的兩點改變,讓樣式的管理更為方便、視覺上更有統整性,自然也會加快樣式上的開發。
而 Sass 與 CSS 變數更大的不同是:Sass 編譯後終究是 CSS,而本篇會用純 CSS 來與大家分享 CSS 變數上的獨特之處,包含:混合不同單位的運算、修改 CSS 變數改變整體畫面等技法。
使用 CSS Variables
使用前,大家最關心的一定是支援度,一樣是 IE 不支援,其他大部分都是支援的,以下附上支援圖(2019 年 12 月 Can I use)。
使用 CSS 變數時也區分為兩個階段:
- 定義變數:CSS Variables 的變數定義必須定義在 CSS 選取器內,大多數來說會建議定義在
:root
最高層級的選取器便於取用。 - 取用變數值:一般來說宣告變數會使用
var {變數名稱}
的方式使用,但在 CSS Variables 則是需要在 取值時 才加入var (變數名稱)
。
接下來開始來撰寫 CSS Variables 吧!
記得兩個步驟,第一個步驟是宣告變數,我們可以將本範例中會運用到的變數都放在 :root
選取器內,並且使用 --自訂名稱
作為屬性的方式來宣告變數。
:root {
--primary: Aquamarine;
--background-color: Teal;
}
接下來來到取值的階段,取值時前方依然是撰寫我們需要套用的樣式屬性,後方再接著使用 var (--變數名稱)
來套用。
body {
background: var(--background-color);
}
範例圖片:
範例網址:https://codepen.io/Wcc723/pen/oNgXraG
變數搭配 RWD!
相對於 Sass 的變數來說,CSS 的變數是可以再次改變的,且改變的方式也是依據 CSS 「後者覆蓋前者」的特性,以下就使用 “中斷點” 做為條件來使後者的樣式覆蓋前者吧。
製作響應式時,因為螢幕大小的不同通常會需要調整文字大小來符合需求,最常見的方式就是透過選取器一一覆蓋字體大小,如果透過變數的方式就可以統一切換整體文字大小,不需要一一的調整每個選取器。
:root {
--font-size: 14px;
}
/* 使用變數定義文字大小 */
p {
font-size: var(--font-size);
}
/* 除此之外,還可以透過 calc 用相同變數做運算,讓特定的文字更大獲更小 */
h1 {
font-size: calc(var(--font-size) * 1.5);
}
接下來只要調整中斷點內的變數,上段的 p
、h1
選取器就會套用新的變數值。
@media (min-width: 480px) {
:root {
--font-size: 18px;
}
}
本範例可透過縮放畫面看到不同結果,建議到範例中觀看,範例網址:https://codepen.io/Wcc723/pen/JjodQVJ
JavaScript 操作 CSS 變數
除了使用覆蓋的方式外,萬能的 JavaScript 也同樣能夠調整 CSS 變數,此方式也就幾乎跳脫所有的限制可自由運用 CSS 變數。
此範例中先預訂了一個變數 --size
,並且給予值 200px。
:root {
--size: 200px;
}
設定 CSS Variables 與設定一般 CSS 屬性方式是相同的,先選取 document.documentElement.root
就能在下方的 style 設定屬性 { '--變數名稱', '值' }
。
const root = document.documentElement;
root.style.setProperty('--size', `${this.value}px`)
範例圖片:
範例網址:https://codepen.io/Wcc723/pen/xxbwXZQ
使用不科學的 Calc 做計算
除此之外,CSS 中更有一個神奇的運算方法 calc
,此函式可以無視讓不同單位的數值直接做運算,如百分比與絕對單位運算(ex: 100% - 30px)。CSS Variables 也同樣能夠搭配此方法產生新的值。
calc 是作為函式使用,因此可將預期運算的方法置入 calc()
的括號內即可。
.box-1 {
width: calc(100% - var(--size));
}
本範例可以透過拖曳 range input 改變寬度的範圍,範例網址看結果:https://codepen.io/Wcc723/pen/OJPVeKd
計算色彩
在 CSS 色彩中除了常見的色碼外(ex: #fff),rgb
、hls
也都是常見的色彩標示方式,這些色彩標示方式都是直接置入 純數值。因此,也可透過 calc
這一個神奇的運算方法來調整它。
此範例使用 rgb、calc 來繪製 CSS 漸層。
/* 定義一個值 */
:root {
--c: 255;
}
/* 搭配不同的運算給予不同的 r, g, b */
body {
background-image: linear-gradient(
rgb(
calc(var(--c) - 60),
calc(var(--c) - 40),
calc(var(--c))
),
rgb(
calc(var(--c) - 20),
calc(var(--c) - 10),
calc(var(--c))
)
);
}
範例圖片:
images
本範例透過調整 input range 會有白天跟黑夜的切換,範例網址看結果:https://codepen.io/Wcc723/pen/OJPyxVM
Bootstrap
除了本文所介紹的範例外,應該也會有許多讀者會疑惑 CSS Variables 還有用在哪些地方呢?其實在最主流的 CSS 函式庫中就有包含 CSS Variables 可以運用,主要用途是讓開發者做自訂元件時可以直接取用,且不需要經過編譯。
CSS variables offer similar flexibility to Sass’s variables, but without the need for compilation before being served to the browser.
可以參考:https://getbootstrap.com/docs/4.4/getting-started/theming/#css-variables
Bootstrap 預設有提供所有的主題色彩作為變數,因此我們套用 Bootstrap 時可不需要另外撰寫色碼,直接可透過變數取得該色彩。
p {
color: var(--primary)
}
本範例直接取用 Bootstrap 變數,範例網址直接看:https://codepen.io/Wcc723/pen/bGNdPmZ