深色模式配色:如何挑選背景、文字與強調色
用 #121212 這類深灰色當背景,不要用純黑;用 #e5e5e5 這類米白色當文字,不要用純白;品牌色則改用更亮、飽和度更低的版本。文字除了用 WCAG 2 檢查,也要用 APCA 檢查,因為 WCAG 2 會高估深色背景上的對比度。
閱讀時間約 1 分鐘
為什麼純黑底配純白字看久了會累
白色 #ffffff 配黑色 #000000 是螢幕能呈現的最大對比:WCAG 2 是 21:1,APCA 是 Lc -107.9。用在按鈕文字上沒問題,用在大段文字上就太強了。
問題出在光暈效應(halation)。黑底上的亮字看起來會把光暈染到周圍的暗處,讓筆畫顯得更粗、更模糊,散光的人尤其明顯。眼睛也會在刺眼的文字和黑色空隙之間不斷調適,長時間閱讀很容易疲勞。
把兩端都往中間收,就能解決問題又不影響可讀性。#121212 上的 #e5e5e5 仍有 14.87:1 和 Lc -90.4,高於 APCA 建議內文使用的 Lc 90。
深色模式最適合的背景色
多數深色主題的背景落在 OKLCH 亮度 0.14 到 0.28 之間。下表列出常見選擇,並搭配兩種文字顏色:#e5e5e5 適合舒適閱讀的內文,#fafafa 用於最強調的地方。
| 表面 | OKLCH L | 常見名稱 | #e5e5e5 文字 | #fafafa 文字 |
|---|---|---|---|---|
| #000000 | 0 | 純黑 | 16.67:1, Lc -91.0 | 20.12:1, Lc -104.6 |
| #0a0a0a | 0.145 | Tailwind v3 neutral-950 | 15.72:1, Lc -90.9 | 18.97:1, Lc -104.4 |
| #121212 | 0.182 | Material Design 深色表面 | 14.87:1, Lc -90.4 | 17.95:1, Lc -104.0 |
| #18181b | 0.210 | Tailwind v3 zinc-900 | 14.06:1, Lc -89.9 | 16.97:1, Lc -103.4 |
| #1f2937 | 0.278 | Tailwind v3 gray-800 | 11.65:1, Lc -87.5 | 14.06:1, Lc -101.0 |
從純黑換成 #18181b,以 APCA 來看幾乎沒有損失:#e5e5e5 文字只從 Lc -91.0 降到 -89.9。換來的是背景以下有空間放陰影,背景以上也有空間放浮起的表面。#1f2937 略帶藍色(彩度 0.03),品牌偏冷色調時很合適,旁邊若是暖色強調色就會顯得不協調。
WCAG 2 會高估深色背景上的對比度
WCAG 2 的公式不管顏色是亮是暗,同一個比值都一視同仁。人眼卻不是這樣:深色之間的差異比較難看出來。APCA 把這一點納入模型,而兩者的差距相當大。下表列出在各種背景上,要達到 WCAG AA 和兩個 APCA 等級需要用哪一種灰色。
| 背景 | 達 4.5:1 的最淺灰色 | 該灰色的 APCA | 達 Lc 60 的灰色 | 達 Lc 75 的灰色 |
|---|---|---|---|---|
| #ffffff | #767676 | Lc 71.6 | #8e8e8e, 3.28:1 | #6e6e6e, 5.10:1 |
| #121212 | #7d7d7d | Lc -32.8 | #b2b2b2, 8.84:1 | #cccccc, 11.67:1 |
| #000000 | #757575 | Lc -29.6 | #b1b1b1, 9.79:1 | #cbcbcb, 12.94:1 |
在白底上,剛好通過 AA 的灰色已經達到 Lc 71.6。在 #121212 上,剛好通過 AA 的灰色只有 Lc -32.8,連 APCA 對大標題要求的最低 Lc 45 都不到。要達到同樣的 APCA 內文等級 Lc 75,白底只需要 5.10:1,#121212 上卻需要 11.67:1。
彩色也一樣。藍色 #4a83f0 在 #121212 上以 5.17:1 通過 WCAG AA,但 APCA 值只有 Lc -37.6。在深色模式中,請把 4.5:1 當成最低門檻。內文建議達到約 9:1 以上,也就是 #121212 上的灰色達到 Lc 60 的位置,或直接用 APCA 檢查。
為什麼不能直接反轉淺色配色
為白色背景調校的品牌色,放到深色背景上通常太暗、太飽和。以淺色主題的藍色 #2f6bdf 為例,在白底上當連結文字有 4.90:1,及格;在 #121212 上則掉到 3.83:1 和 Lc -27.7,任何字級都不及格。
解法是在品牌色階上往淺的方向移:提高亮度、降低彩度。下表比較同一組藍色色階中的四階在兩種背景上的表現。
| 色階 | 顏色 | OKLCH | 在 #ffffff 上 | 在 #121212 上 |
|---|---|---|---|---|
| 600 | #2f6bdf | oklch(55.5% 0.188 261.8) | 4.90:1, Lc 73.4 | 3.83:1, Lc -27.7 |
| 500 | #4a83f0 | oklch(62.7% 0.175 261.9) | 3.62:1, Lc 63.5 | 5.17:1, Lc -37.6 |
| 400 | #6f9ef4 | oklch(70.3% 0.137 261.7) | 2.67:1, Lc 51.7 | 7.02:1, Lc -49.6 |
| 300 | #a3c0f5 | oklch(80.5% 0.082 262.3) | 1.84:1, Lc 34.5 | 10.18:1, Lc -67.5 |
對連結和彩色文字來說,300 階就是深色模式中的 600 階:亮度從 0.555 提高到 0.805,彩度從 0.188 降到 0.082,不到原本的一半。降低彩度也很重要,因為高飽和的顏色在深色背景上看起來會發光,邊緣還會閃動。
實心按鈕則不同,因為按鈕自帶背景。#2f6bdf 上的白字在兩種主題中都維持 4.90:1,所以主要按鈕可以不變。只有彩色文字、圖示和外框需要改用較淺的色階。
層級:用更亮的表面取代陰影
陰影在深色背景上幾乎看不見,所以深色主題改用亮度來表現高度:表面越靠近使用者,就越亮。Material Design 最初的深色主題做法是在 #121212 上疊一層白色,從 1 dp 高度(用於卡片)的 5%,到 24 dp 高度(用於對話框)的 16%。
| 層級 | 白色疊加 | 結果 | OKLCH L | 與底色對比 | #e5e5e5 文字 |
|---|---|---|---|---|---|
| 0 dp,背景 | 0% | #121212 | 0.182 | 1:1 | 14.87:1 |
| 1 dp,卡片 | 5% | #1e1e1e | 0.235 | 1.12:1 | 13.23:1 |
| 3 dp | 8% | #252525 | 0.264 | 1.22:1 | 12.17:1 |
| 6 dp | 11% | #2c2c2c | 0.293 | 1.34:1 | 11.09:1 |
| 12 dp | 14% | #333333 | 0.321 | 1.48:1 | 10.03:1 |
| 24 dp,對話框 | 16% | #383838 | 0.341 | 1.60:1 | 9.31:1 |
每一層大約增加 0.02 到 0.05 的 OKLCH 亮度。就連最高層和背景也只差 1.60:1,所以需要突顯的表面請加上 1 px 邊框。用 OKLCH 可以不靠疊加寫出同一套系統:彩度和色相不變,每一層把 L 提高約 0.03。
prefers-color-scheme 與 color-scheme 屬性
prefers-color-scheme 媒體查詢能告訴你作業系統設定的是淺色還是深色。color-scheme 屬性則告訴瀏覽器你的頁面支援哪些配色模式,讓它用相符的顏色繪製捲軸、表單控制項和預設畫布。
在根元素上設定 color-scheme,再到媒體查詢裡覆寫你的顏色變數。
CSS
:root {
color-scheme: light dark;
--bg: #ffffff;
--surface: #f4f5f6;
--text: #15171b;
--text-muted: #6e7279;
--link: #2f6bdf;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #121212;
--surface: #1e1e1e;
--text: #e5e5e5;
--text-muted: #b2b2b2;
--link: #a3c0f5;
}
}
body {
background: var(--bg);
color: var(--text);
}少了 color-scheme,多數瀏覽器在深色頁面上仍會顯示淺色捲軸和白色輸入框。只要一行,卻很容易忘記。
CSS 的 light-dark() 函式
light-dark() 接受兩個顏色,在淺色模式下回傳第一個,在深色模式下回傳第二個。自 2024 年起所有主流瀏覽器都已支援:Chrome 和 Edge 123、Firefox 120、Safari 17.5。它會讀取 color-scheme 屬性:沒有設定 color-scheme: light dark 時,永遠回傳淺色的值。
每個顏色只宣告一次,和對應的深色值放在一起,切換主題時只需要改 color-scheme。
CSS
:root {
color-scheme: light dark;
--bg: light-dark(#ffffff, #121212);
--surface: light-dark(#f4f5f6, #1e1e1e);
--text: light-dark(#15171b, #e5e5e5);
--text-muted: light-dark(#6e7279, #b2b2b2);
--link: light-dark(#2f6bdf, #a3c0f5);
--primary: #2f6bdf;
--on-primary: #ffffff;
}
:root[data-theme='light'] {
color-scheme: light;
}
:root[data-theme='dark'] {
color-scheme: dark;
}在頁面背景上,這段程式碼中的每個文字顏色在兩種主題下都通過 AA。淺色主題:文字 17.94:1,弱化文字 4.83:1,連結 4.90:1。深色主題:文字 14.87:1,弱化文字 8.84:1(Lc -60.1),連結 10.18:1。你可以在 PickShade 對比度檢查工具中檢查自己的任何配對,它會並列顯示 WCAG 2 和 APCA。
常見問題
深色模式最適合用什麼背景色?
非常深的灰色比純黑更好。Material Design 建議的 #121212 和 #18181b 都是常見選擇。#121212 上的米白色文字(例如 #e5e5e5)在 WCAG 2 有 14.87:1,在 APCA 有 Lc -90.4,好讀又沒有黑底白字的刺眼感。
深色模式該用純黑 #000000 嗎?
文字多的畫面通常不建議。純黑上的白字有 21:1 的最大對比,會產生光暈效應:亮字看起來像是滲進黑色裡,顯得模糊,散光的人尤其明顯。深灰色背景配米白色文字讀起來更舒服。
深色模式的文字該用什麼顏色?
內文用 #e5e5e5 這類米白色,次要文字用 #b2b2b2 左右的淺灰色。它們在 #121212 上分別是 14.87:1 和 8.84:1。避免使用剛好通過 4.5:1 的中灰色,因為在深色背景上它們實際上比比值所顯示的難讀得多。
品牌色要怎麼調整成深色模式?
改用同一組色階中更亮、飽和度更低的一階。像 #2f6bdf 這樣的藍色在白底上以 4.90:1 及格,但在 #121212 上只有 3.83:1。它較淺的色階 #a3c0f5 在 #121212 上有 10.18:1,OKLCH 亮度從 0.555 提高到 0.805,彩度從 0.188 降到 0.082。
WCAG 對比度在深色模式下準確嗎?
WCAG 2 會高估深色之間的對比。在 #121212 上剛好通過 4.5:1 的灰色,APCA 只有 Lc -32.8;而在白底上通過 4.5:1 的灰色可達 Lc 71.6。深色模式的內文建議達到約 9:1 以上,或同時用 APCA 檢查。
CSS 的 light-dark() 有什麼作用?
當元素使用淺色配色模式時,light-dark() 回傳第一個顏色;使用深色配色模式時則回傳第二個。它需要先設定 color-scheme 屬性,例如在 :root 上寫 color-scheme: light dark,自 2024 年起所有主流瀏覽器都已支援。