跳至主要内容

如何幫網站新增一個 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-shadowborder-radiusorder 這類結構型樣式,通常不夠用。

2. 完整替換整份 CSS

直接維護兩份完整 CSS(例如 default.csstheme.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 覆蓋會是最平衡的做法。