如何幫網站新增一個 Theme
· 閱讀時間約 2 分鐘
前言
今天想嘗試幫網站做一個 theme。
以前我也曾經做過幾次修改,比如說「聖誕節主題」、「抹茶主題」等等。
原本我都是直接去修改 styles.css,後來發現這樣要做「期間限定」的 Theme 不是很方便。
所以我就把一些常見的顏色改成參數,可以直接用參數改變顏色,直接幫網站換 Theme。但有時候是連結構都會改變,這時候只改變數就不太夠用了(搞得太複雜也不好維護)。
所以呢,以下整理介紹三種常見的 Theme 做法:
1. CSS 變數切換
先把顏色、字體、間距等抽成 CSS 變數(Custom Properties),切換 Theme 時只要替換一組變數值。
/* 預設主題 */
:root {
--color-bg: #fff;
--color-text: #333;
}
/* 另一個 Theme */
:root[data-theme="retro"] {
--color-bg: #f2f2f2;
--color-text: #111;
}
- 優點: 最輕量,只需維護一份 CSS。
- 缺點: 只能改到已經參數化的屬性。像
box-shadow、border-radius、order這類結構型樣式,通常不夠用。
2. 完整替換整份 CSS
直接維護兩份完整 CSS(例如 default.css、theme.css),切換時整份替換。
- 優點: 兩份 CSS 完全獨立,不需要考慮覆蓋衝突。
- 缺點: 維護成本最高,共用元件的修改要同步兩份。
3. CSS 覆蓋(Override)
保留原本的 styles.css,再額外新增一份 theme.css,只覆蓋需要改動的規則。
.post-card {
background: #f2f2f2;
border-radius: 0;
}
- 優點: 可以覆蓋任意屬性,不受限於變數;原本 CSS 幾乎不用動,載入即套用、移除即還原。
- 缺點: 需要注意 CSS 優先權(specificity)與載入順序,必要時要調整選擇器權重。
實作上,只要在 HTML 的 <head> 多載入一行:
<link rel="stylesheet" href="/assets/css/styles.css">
<link rel="stylesheet" href="/assets/css/theme.css"> <!-- 加這行 -->
theme.css 直接用相同選擇器覆蓋 styles.css。由於它在後面載入,在相同優先權下會覆蓋前者(CSS cascade)。
如果要做即時切換
可以用 JS 搭配 body class 做 runtime 切換:
document.body.classList.toggle('theme-alt');
這時候,Theme 規則就要加上 body.theme-alt 前綴:
body.theme-alt .post-card { ... }
body.theme-alt .post-title { ... }
如果你要的是「快速上線、可恢復、又能改結構樣式」,通常 CSS 覆蓋會是最平衡的做法。