簡單實現 Dark Mode/Light Mode 的切換

近幾年來 Light/Dark Mode 愈來愈盛行,最近工作上也開始要實作 Light/Dark Mode 的切換,而 CSS Variables 的出現讓實現這件事變得更加方便,趁著這次機會好好記錄一下練習過程。

Carol Yan
新加坡商鈦坦科技
7 min readJan 3, 2024

--

Photo by Mohammad Rahmani on Unsplash
目錄
1. 為什麼分享這個主題?
2. CSS Variables
3. prefers-color-scheme
4. 結語
5. 參考來源

為什麼分享這個主題?

近幾年來 Light/Dark Mode 愈來愈盛行,最近工作上也開始要實作 Light/Dark Mode 的切換,而 CSS Variables 的出現讓實現這件事變得更加方便,趁著這次機會好好記錄一下練習過程。

CSS Variables

CSS Variables支援度:Can I Use

通常同一套 layout 如果要切換不同主題,都是在最外層套上主題class,如下:

/* template */
<div class="container" class="dark">
...
</div>

以往每轉換一個主題,需要針對每一個要轉換樣式的元素重新進行調整,而這種方式,有可能會漏改元素以及讓程式碼非常繁複。如下:

/* Style for Light Theme */
.light section{
background:white;
}
.light p{
color:black;
}
.light a{
color:blue;
}

/* Style for Dark Theme */
.dark section{
background:black;
}
.dark p{
color:white;
}
.dark a{
color:aqua;
}
...

有了CSS Variables,只要在根元素設定好變數,根據不同的主題切換,這些變數會隨著不同主題的切換而自動調整,使得程式碼變得更簡潔且易於維護,不再需要為每個元素單獨設定樣式,而且主題切換也更加輕鬆。如下:

/* CSS Variables Setting */
:root{
background:var(--background-primary);
color:var(--text-primary);
accent-color:var(--accent-primary);
}

/* CSS Variables for Light Theme */
.light{
--background-primary:white;
--text-primary:black;
--accent-primary:blue;
}

/* CSS Variables for Dark Theme */
.dark{
--background-primary:black;
--text-primary:white;
--accent-primary:aqua;
}

/* Common Styles */
section{
background:var(--background-primary);
}
p{
color:var(--text-primary);
}
a{
color:var(--accent-primary);
}
...

Codepen 範例

IT15-Day03-Create A Dark/Light Mode Switch with CSS Variables
參考 MDN 寫的一個小範例,大家可以試試看!

(範例圖片來源:MDN

Dark theme example
Dark theme example
Light theme example
Light theme example

color-constract:一個實驗中的 CSS 屬性,會從列出的顏色中找出一個對比度最高的,如果之後支援度變高,感覺可以更便利的設定各種主題下的文字顏色

prefers-color-scheme

支援度:Can I Use

接續上面的 Dark Mode/Light Mode 切換,在網頁最外層套上主題 class,但如果想要一開始就自動根據使用者的系統設定給予相對應的 theme 呢?

CSS 出了一個 media 特性 prefers-color-scheme,可以自動檢測使用者:

  1. 是否支援主題切換
  2. 是否將系統設定為亮色或暗色主題
    如果為true,則可以使用prefers-color-scheme
@media (prefers-color-scheme:light){
.container{
background:#fff;
color:#1b1b1b;
}
}
@media (prefers-color-scheme:dark){
.container{
background:#1b1b1b;
color:#fff;
}
}

結合上面的 CSS 變數的另種寫法:

.container{
background:var(--background-primary);
color:var(--text-primary);
}
@media (prefers-color-scheme:light){
:root{
--background-primary:#fff;
--text-primary:#1b1b1b;
}
}
@media (prefers-color-scheme:dark){
:root{
--background-primary:#1b1b1b;
--text-primary:#fff;
}
}

Codepen 範例

IT15-Day04-Create A Dark/Light Mode Switch with prefers-color-scheme
參考 MDN 寫的一個小範例,大家可以試試看!

Automatically detect the user’s theme, as shown in the figure is the dark theme
Automatically detect the user’s theme, as shown in the figure is the dark theme
Automatically detect the user’s theme, as shown in the figure is the light theme
Automatically detect the user’s theme, as shown in the figure is the light theme

2023/09/19 實測發現:
主題偵測的是系統(裝置)的 Light Mode/Dark Mode 變換,而不是瀏覽器的 Light Mode/Dark Mode。

結語

這篇文章介紹了兩種實現 Dark Mode/Light Mode 的CSS語法

CSS Variables:在切換 theme 時可以只切換所有變數的樣式,既不容易漏掉又快速

prefers-color-scheme:可以自動根據使用者系統 theme 的設定,在打開網頁時就給予一致性的視覺感受

而這兩種通常會一起使用,這樣可以在一開始就可以根據使用者系統設定的 theme 給予相對應的 theme,且也可以讓使用者自由切換

想要看更多 CSS 文章,歡迎來看我今年的鐵人賽文章-你應該要知道的 CSS 技巧:發掘被忽略但實用的屬性

--

--