color-scheme 屬性會指出網頁支援的色彩配置 (例如淺色或深色)。這會通知瀏覽器,可以自動設定原生 UI 元素 (例如捲軸、表單控制項和預設畫布背景) 的主題,以符合網站設計,並盡可能減少初始載入期間的白色閃爍。
導入作業
1. 在 HTML 中宣告支援的配置
強制:為避免「未套用主題的內容閃爍」(FOUC),請在 <head> 中加入 <meta> 標記,確保瀏覽器在開始算繪前,就知道你支援哪些主題。雖然這個 <meta> 標記可提早設定初始畫布顏色,有助於避免 FOUC,但可能無法完全消除所有瀏覽器或載入條件下的閃爍情形。
<!-- MANDATORY: Declare support for both light and dark themes -->
<meta name="color-scheme" content="light dark">
2. 將全頁色彩配置套用至 CSS :root 或 HTML
必要:將 color-scheme 屬性套用至 html 元素或 :root 虛擬類別。瀏覽器會特別查看根元素,判斷整個可視區域的主題,包括根捲軸和初始「畫布」背景。如果只套用至 body,這些全域 UI 介面可能會維持在淺色模式,因為 body 無法控制視窗的轉譯內容。
/* MANDATORY: Apply color-scheme to :root or html for viewport-wide theming */
:root {
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
3. 定義淺色和深色權杖
您可以使用 light-dark() 函式定義顏色符記,自動配合不同的 color-scheme 值調整。
建議您也將原始顏色值保留在不同的自訂屬性中,這樣就能更輕鬆地以不同方式組合這些值 (並在需要時簡化備用行為)。
如要進一步控管 accent-color 或 scrollbar-color 等內建 UI 的顏色,作者可以選擇使用自訂屬性和/或 light-dark() 函式,新增自己的動態顏色。這個函式會根據元素計算出的 color-scheme 自動選擇正確的顏色,不需要多餘的媒體查詢,但基本實作不需要這個函式。
:root {
--color-brand-light: oklch(45% 0.23 270);
--color-brand-dark: oklch(85% 0.15 210);
--color-brand-text-light: white;
--color-brand-text-dark: oklch(40% 0.23 270);
--color-brand: light-dark(var(--color-brand-light), var(--color-brand-dark));
--color-brand-text: light-dark(var(--color-brand-text-light), var(--color-brand-text-dark));
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
button.primary {
/* These automatically adapt to color scheme */
background-color: var(--color-brand);
color: var(--color-brand-text);
}
選用:有多種系統顏色可供使用,也會自動配合使用的色彩配置 (和其他色彩模式,例如強制顏色),例如 canvas、canvastext、accentcolor (檢查支援)、buttonborder 等。這些顏色通常太有限,除了需要完全符合特定預設瀏覽器 UI 或做為備用/預設值的特定情況外,其他情況都不適用。
選用:根據情境調整顏色組合
即使覆寫系統預設值,使用 prefers-color-scheme 媒體查詢定義不同顏色組合仍有其用處,因為這會考量網頁周圍的瀏覽器和 OS Chrome 顏色 (或網頁做為 iframe 時周圍網頁的顏色)。
舉例來說,當系統設定為 dark 時,請使用稍微偏暗的淺色主題;當系統設定為 light 時,請使用對比度較高的深色主題,這樣網頁就不會被周圍的 UI 遮蓋。
精細自訂瀏覽器 UI
設定 color-scheme 後,瀏覽器 UI 就會根據使用的色彩配置調整,但這會採用 OS 預設值和/或系統顏色,可能與網站設計不完全一致。新式瀏覽器會為這些項目提供多個精細的自訂掛鉤。請勿為了自訂外觀而重新實作原生控制項,除非您已用盡新式瀏覽器提供的自訂掛鉤。
設定強調色
部分瀏覽器 UI (例如勾選的核取方塊或滑桿) 會使用強調色。根據預設,這會解析為 OS 設定,但您可以使用 accent-color 屬性,將其設為更符合網頁的顏色,例如網頁的品牌顏色。
html {
accent-color: light-dark(var(--color-accent-light), var(--color-accent-dark));
}
使用 accent-color 時應注意的問題
瀏覽器轉譯 accent-color 的方式不盡相同。
對於通常繪製在強調色背景上的指標 (例如核取方塊標記和圓形按鈕點),瀏覽器可能會採用不同的處理方式:
- Chromium 和 Firefox 通常會選取對比鮮明的指標顏色。
- Safari 則可能會在淺色模式下保留白色指標,或在深色模式下保留黑色指標,同時修改指標後方的強調色。這項調整不一定能為所有提供的顏色提供足夠的對比度,因此請在 Safari 中測試重要組合,包括淺色和深色色彩配置。請勿假設 Safari 會自動選擇對比度最佳的指標顏色。
捲軸顏色
您可以搭配使用 scrollbar-color 和 light-dark(),設定符合所用色彩配置的自訂捲軸顏色。
:root {
--color-scrollbar-track: light-dark(#eee, #222);
--color-scrollbar-thumb: light-dark(#999, #666);
scrollbar-color: var(--color-scrollbar-thumb) var(--color-scrollbar-track);
}
使用 scrollbar-color 時應注意的問題
- 請勿為
scrollbar-color加上動畫或轉場效果。WebKit 錯誤會導致捲軸在每次scrollbar-color變更時閃爍。 - 在 macOS 上,系統預設會忽略
scrollbar-color(標準) 和::-webkit-scrollbar(舊版) 屬性,因為 macOS 使用原生「疊加」捲軸。您必須將自訂顏色與scrollbar-width(例如thin或auto) 搭配使用,強制 macOS 轉譯這些顏色。 - 即使套用
scrollbar-width,macOS 疊加捲軸預設仍會將軌道 (邊線) 算繪為透明。如果設計要求在 MacOS 上顯示可見的軌道背景顏色,您必須將scrollbar-gutter: stable;套用至可捲動容器,但請注意,只有在使用者將滑鼠游標懸停在捲軸上時,才會顯示。 - 即使使用
scrollbar-gutter: stable,在 macOS 上,軌道仍可能呈現透明。滑桿不應依賴軌道顏色來顯示。
進一步自訂
大多數瀏覽器 UI 都會公開虛擬元素,以便完整自訂外觀,例如:
::placeholder::spelling-error::grammar-error::selection::search-text::target-text::file-selector-button
您可以在上述任何項目上使用 light-dark() 顏色,套用會根據所用色彩配置調整的顏色。
4. 淺色和深色模式的圖片不同
如果是 CSS 圖片,light-dark() 也可以用來提供不同的圖片值。
重要事項:light-dark() 中的兩個值必須屬於相同類型。無法同時使用顏色和圖片。
如果其中一個必須是圖片,請使用 image(<color>) 包裝顏色值。
以 JS 為基礎的主題偵測
大多數色彩配置分支應在 CSS 中完成,CSS 會自動配合變更調整。
任何讀取 matchMedia("(prefers-color-scheme: dark)").matches 的 JS 也必須處理其 change 事件,因為系統偏好設定隨時可能變更。
選用:導入色彩配置切換鈕
如要允許使用者手動覆寫這個網站的系統預設值,可以實作深色模式切換鈕。大多數網站不需要在網站 UI 中提供永久切換鈕。 通常只要預設為系統色彩配置即可,也可以在獨立的設定介面中進行設定。如要瞭解實作深色模式切換鈕 (永久或非永久) 的最佳做法,請參閱「深色模式切換鈕」。
選用:元件專屬覆寫
您可以為特定元素設定 color-scheme,覆寫全域主題。
如需更多資訊和注意事項,請參閱「元件專屬淺色/深色主題」。
已知問題
使用 color-scheme 時應注意的問題
- Chrome 和 Firefox 會遵循 iframe 的
color-scheme:以正確的色彩配置算繪嵌入頁面,並調整嵌入頁面的prefers-color-scheme媒體查詢,以反映嵌入內容的color-scheme。Safari 則不會,即使在 iframe 內,也會將prefers-color-scheme解析為系統設定。- 如果您同時控制父項和 iframe:請在 iframe 建構時,透過網址參數 (
?theme=dark) 或postMessage()(也可讓您回應執行階段變更),明確將父項的色彩配置傳遞至 iframe。在 iframe 中,根據該信號在<html>上設定類別 (和/或在:root上設定color-scheme),而不是依賴prefers-color-scheme。 - 如果您只能控制嵌入網頁:在 Safari 中,無法可靠地從 iframe 內偵測嵌入內容的
color-scheme。在嵌入 API 上公開明確的主題參數 (例如查詢字串或postMessage通訊協定),並為嵌入者提供說明文件。
- 如果您同時控制父項和 iframe:請在 iframe 建構時,透過網址參數 (
備用策略
color-scheme 的備用方案和瀏覽器支援
color-scheme 屬性是漸進增強。不支援這項屬性的瀏覽器會忽略該屬性,並使用預設的淺色模式 UI。
如要配合使用者在舊版瀏覽器中的偏好設定,請使用 prefers-color-scheme 媒體查詢,在使用者偏好深色模式時提供不同顏色。
- 務必使用媒體查詢,切換
:root或html的自訂屬性 - 除非元件需要顏色以外的特定深色模式自訂設定,否則請避免在個別元件上使用媒體查詢。
:root {
/* Define brand colors for each mode */
--color-brand-light: #0056b3;
--color-brand-dark: #00e5ff;
--color-brand: var(--color-brand-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--color-brand: var(--color-brand-dark);
}
/* Ignored in older browsers */
color-scheme: light dark;
}
button.primary {
background-color: var(--color-brand);
}
light-dark() 的備用方案和瀏覽器支援
如果瀏覽器支援 color-scheme,但尚未支援 light-dark(),則應先將顏色的淺色和深色版本定義為自訂屬性,並使用 prefers-color-scheme 媒體查詢設定各個模式的顏色,如以下範例所示:
:root {
/* Define browser UI accent color for each mode */
--brand-accent-light: #0056b3;
--brand-accent-dark: #00e5ff;
--accent-color: var(--brand-accent-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--accent-color: var(--brand-accent-dark);
}
/* OPTIONAL: use light-dark() for more control of built-in UI colors */
@supports (color: light-dark(white, black)) {
--accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
}
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
/* Example inherited color property */
accent-color: var(--accent-color);
}
pre, code {
color-scheme: dark;
/* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
accent-color: var(--accent-color);
}
light-dark() 圖片值的備用方案和瀏覽器支援
如果瀏覽器不支援圖片的 light-dark(),請使用 image-set() 做為切換:為每個選項提供自訂屬性的 type(),並將未啟用的選項設為不支援的 MIME 類型,讓瀏覽器捨棄該選項。啟用選項會取得空值,因此是沒有 type() 的一般 image-set() 選項。
在 :root 上定義一次切換鈕。這樣一來,每個使用網站就只需要內嵌這兩張圖片,例如 light-dark()。
:root {
--light-type: ;
--dark-type: type("image/do-not-use");
/* MANDATORY: Fallback for browsers without light-dark() image support */
@media (prefers-color-scheme: dark) {
--light-type: type("image/do-not-use");
--dark-type: ;
}
}
.hero {
background-image: image-set(url(hero-light.png) var(--light-type), url(hero-dark.png) var(--dark-type));
@supports (background-image: light-dark(url("a"), url("b"))) {
background-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
- 系統只會下載所選圖片。
- 解決方案仍有效:
image-set(url(a-1x.png) 1x var(--light-type), url(a-2x.png) 2x var(--light-type), url(b-1x.png) 1x var(--dark-type), url(b-2x.png) 2x var(--dark-type))。 - 請勿使用
type("")做為啟用選項。瀏覽器會將空字串視為不支援,並捨棄所有選項。 - 與
light-dark()不同,切換鈕不會遵循在子樹上設定的color-scheme。手動切換鈕或任何設定color-scheme的子樹狀結構,也必須翻轉--light-type和--dark-type。
替代方案:每張圖片一個自訂屬性
如果只有少數圖片不同,這種做法比較簡單,但每張圖片都需要自己的媒體查詢分支,而且必須手動切換每個分支。
:root {
--hero-image: url(hero-light.png);
@media (prefers-color-scheme: dark) {
--hero-image: url(hero-dark.png);
}
@supports (background-image: light-dark(url("a"), url("b"))) {
--hero-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
.hero {
background-image: var(--hero-image);
}
image() 的備用方案和瀏覽器支援
使用單一顏色停駐點且不含位置的漸層,例如 linear-gradient(blue)。
如要支援更多瀏覽器,可以明確提供單一顏色停止點的 0 100% 位置,例如 linear-gradient(blue 0 100%)。
scrollbar-color 的備用方案和瀏覽器支援
這項功能是漸進增強功能,不一定需要備用廣告。
如果樣式很重要,且使用者的基準目標是「基準廣泛可用」或更早版本,則應加入非標準 ::-webkit-scrollbar 虛擬元素做為備用。
在 @supports not (scrollbar-color: auto) 區塊中納入舊版備用屬性,避免在原生支援標準屬性和舊版 WebKit 選取器的瀏覽器中,發生兩者衝突的情況。
如果您使用自訂屬性定義顏色,這些屬性會自動套用至舊版 WebKit 選取器。您「不」需要複製這些項目。
/* Legacy fallback for WebKit/Blink browsers */
@supports not (scrollbar-color: auto) {
.scroller::-webkit-scrollbar {
/* Must define base size in WebKit for custom colors to be visual */
width: 12px;
height: 12px;
}
.scroller::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
}
.scroller::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
}
accent-color 的備用方案和瀏覽器支援
accent-color 屬性是漸進增強。不支援這項屬性的瀏覽器會忽略該屬性,並使用預設的使用者介面顏色。