使用色彩配置 CSS 屬性和對應的中繼標記改善深色模式預設樣式

color-scheme CSS 屬性和相應的中繼標記可讓開發人員選擇網頁採用使用者代理程式樣式表的特定主題預設值。

背景

prefers-color-scheme 使用者偏好設定媒體功能

prefers-color-scheme 使用者偏好設定媒體功能可讓開發人員完全掌控網頁外觀。如果您不熟悉深色模式,請參閱我的文章「prefers-color-scheme: Hello darkness, my old friend」,其中記錄了我對打造出色的深色模式體驗所知的一切。

文章中只簡略提及的拼圖片段是 color-scheme CSS 屬性和同名對應的 meta 標記。這兩種方法都能讓您在開發人員的作業中更輕鬆,因為您可以選擇讓頁面採用使用者代理程式樣式表單的特定主題預設值,例如表單控制項、捲軸列以及 CSS 系統顏色。同時,這項功能可防止瀏覽器自行套用任何轉換。

瀏覽器支援

prefers-color-scheme

瀏覽器支援

  • Chrome:76。
  • Edge:79。
  • Firefox:67。
  • Safari:12.1 版。

資料來源

color-scheme

瀏覽器支援

  • Chrome:81。
  • Edge:81。
  • Firefox:96。
  • Safari:13.

資料來源

使用者代理程式樣式表

在繼續之前,讓我簡單說明什麼是使用者代理程式樣式表單。在大多數情況下,您可以將「使用者代理程式」(UA) 視為「瀏覽器」(browser) 的華麗說法。通用 Analytics 樣式表會決定網頁的預設外觀和感受。如其名所示,UA 樣式表會依據相關的使用者代理程式而定。您可以查看 Chrome (和 Chromium) 的 UA 樣式表,並與 FirefoxSafari (和 WebKit) 的樣式表進行比較。通常,UA 樣式表單會在大部分情況下達成共識。舉例來說,兩者都會將連結設為藍色、一般文字設為黑色,並將背景顏色設為白色,但也有重要的 (有時令人困擾) 差異,例如兩者設定表單控制項樣式的做法。

進一步瞭解 WebKit 的 UA 樣式表,以及這項功能在深色模式中的運作方式。(在樣式表中執行全文搜尋,找出「dark」)。樣式表提供的預設值會根據深色模式的開啟或關閉狀態而變更。為說明這一點,以下提供一個 CSS 規則,其中使用 :matches 擬造類別和 -apple-system-control-background 等 WebKit 內部變數,以及 WebKit 內部預處理器指令 #if defined

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

您會發現上述 colorbackground-color 屬性有部分非標準值。text-apple-system-control-background 都不是有效的 CSS 顏色。這些是 WebKit 內部的語意顏色。

事實上,CSS 已將語意系統顏色標準化。這些值已在 CSS 顏色模組第 4 級中指定。舉例來說,Canvas (請勿與 <canvas> 標記混淆) 是用於應用程式內容或文件的背景,而 CanvasText 則是用於應用程式內容或文件中的文字。這兩者是相輔相成,不應單獨使用。

UA 樣式表可以使用專屬或標準化語意系統顏色,決定 HTML 元素的預設顯示方式。如果作業系統設為深色模式或使用深色主題,CanvasText (或 text) 會依條件設為白色,Canvas (或 -apple-system-control-background) 則會設為黑色。接著,UA 樣式表只會指派一次下列 CSS,並涵蓋淺色和深色模式。

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

color-scheme CSS 屬性

CSS 色彩調整模組第 1 級規格引進了模型,並控制使用者代理程式自動調整色彩的情形,目的是處理使用者偏好設定,例如深色模式、對比調整或特定所需色彩配置。

其中定義的 color-scheme 屬性可讓元素指出適合轉譯的配色方案。系統會根據使用者的偏好設定協調這些值,並選擇色彩配置,進而影響使用者介面 (UI) 的元素,例如表單控制項和捲軸列的預設顏色,以及 CSS 系統顏色使用的值。目前所支援的值如下:

  • normal 表示元素完全不瞭解色彩配置,因此應使用瀏覽器的預設色彩配置來算繪元素。

  • [ light | dark ]+ 表示元素已知曉並可處理所列的色彩配置,並表示這些色彩配置之間的偏好順序。

在這個清單中,light 代表淺色色彩配置,背景顏色淺,前景顏色深;dark 則代表相反的色彩配置,背景顏色深,前景顏色淺。

對於所有元素,使用色彩配置進行轉譯時,所有瀏覽器提供的 UI 元素所使用的顏色應與色彩配置的意圖相符。例如捲軸列、拼字檢查底線、表單控制項等。

:root 元素上,使用色彩配置進行轉譯時,必須影響畫布的表面顏色 (也就是全域背景顏色)、color 屬性的初始值,以及系統顏色的使用值,並且應影響檢視區的捲動條。

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

color-scheme 中繼標記

如要遵循 color-scheme CSS 屬性,必須先下載 CSS (如果是透過 <link rel="stylesheet"> 參照) 並進行剖析。為協助使用者代理程式立即以所需色彩配置算繪網頁背景,您也可以在 <meta name="color-scheme"> 元素中提供 color-scheme 值。

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

結合 color-schemeprefers-color-scheme

由於中繼標記和 CSS 屬性 (如果套用至 :root 元素) 最終都會產生相同的行為,因此我總是建議透過中繼標記指定色彩配置,讓瀏覽器能更快採用所需的配置。

雖然絕對基準網頁不需要額外的 CSS 規則,但一般來說,您應該一律將 color-schemeprefers-color-scheme 結合使用。舉例來說,WebKit 和 Chrome 用於經典連結藍色 rgb(0,0,238) 的專屬 WebKit CSS 顏色 -webkit-link,在黑色背景上的對比率為 2.23:1,不足以達到 WCAG AA 和 WCAG AAA 規定門檻

我已為 ChromeWebKitFirefox 開啟錯誤,以及HTML 標準中的元問題,以便修正這個問題。

prefers-color-scheme 互動

color-scheme CSS 屬性和對應的 Meta 標記與 prefers-color-scheme 使用者偏好設定媒體功能的互動關係,一開始可能會讓人感到困惑。事實上,兩者搭配得非常好。最重要的是,color-scheme 專門用於決定預設外觀,而 prefers-color-scheme 則用於決定可樣式的外觀。為了讓這項概念更清楚,請假設下列網頁:

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

網頁上的內嵌 CSS 程式碼會在一般情況下將 <fieldset> 元素的 background-color 設為 gainsboro,如果使用者偏好 dark 配色方案,則會將其設為 darkslategray,這取決於 prefers-color-scheme 使用者偏好媒體功能。

透過 <meta name="color-scheme" content="dark light"> 元素,網頁會告知瀏覽器,它支援深色和淺色主題,並偏好深色主題。

視作業系統是否設為深色或淺色模式而定,整個網頁會根據使用者代理程式樣式表顯示淺色或深色,反之亦然。沒有其他開發人員提供的 CSS,用於變更段落文字或頁面背景顏色。

請注意,<fieldset> 元素的 background-color 會根據是否啟用深色模式而變更,並遵循開發人員在頁面上提供的內嵌樣式表單中的規則。可以是 gainsborodarkslategray

淺色模式的頁面。
淺色模式:開發人員和使用者代理程式指定的樣式。文字為黑色,背景為白色,符合使用者代理程式樣式表單。<fieldset> 元素的 background-colorgainsboro,如同內嵌的開發人員樣式表所示。
以深色模式顯示的網頁。
深色模式:開發人員和使用者代理程式指定的樣式。 文字為白色,背景則根據使用者代理程式樣式表為黑色。<fieldset> 元素的 background-colordarkslategray,如同內嵌的開發人員樣式表所示。

<button> 元素的外觀由使用者代理程式樣式表控制。其 color 設為 ButtonText 系統顏色,而其 background-color 和四個 border-color 則設為系統顏色 ButtonFace

使用 ButtonFace 屬性的淺色模式頁面。
淺色模式:background-color 和各種 border-color 都設為 ButtonFace 系統顏色。

請注意 <button> 元素的 border-color 如何變化。border-top-colorborder-bottom-color計算值會從 rgba(0, 0, 0, 0.847) (偏黑) 切換為 rgba(255, 255, 255, 0.847) (偏白),因為使用者代理程式會根據色彩配置動態更新 ButtonFace。同樣適用於 <button> 元素的 color,該元素已設為對應的系統顏色 ButtonText

顯示計算出的色彩值與 ButtonFace 相符。
淺色模式:在使用者代理程式樣式表中,border-top-colorborder-bottom-color 的計算值現在都已設為 ButtonFace,而 rgba(0, 0, 0, 0.847) 則設為 rgba(0, 0, 0, 0.847)
顯示在深色模式下,計算的顏色值仍與 ButtonFace 相符。
深色模式:在使用者代理程式樣式表單中,border-top-colorborder-bottom-color 的計算值現在都已設為 ButtonFace,而非 rgba(255, 255, 255, 0.847)

示範

您可以在 Glitch 上的示範中,查看 color-scheme 套用至大量 HTML 元素的效果。本示範「刻意」顯示 WCAG AA 和 WCAG AAA 違規,並使用上述警告中提及的連結顏色。

在淺色模式下進行的展示。
示範切換為 color-scheme: light
深色模式下的示範畫面。
示範切換為 color-scheme: dark。請注意 WCAG AA 和 WCAG AAA 違規事項 的連結顏色。

特別銘謝

color-scheme CSS 屬性和對應的 Meta 標記是由 Rune Lillesveen 實作。Rune 也是 CSS 色彩調整模組第 1 級規格的共同編輯者。主頁橫幅圖片由 Philippe Leone 提供,圖片來源:Unsplash