使用 Baseline CSS 功能的色彩主題

David A. Herron
David A. Herron

發布日期:2025 年 12 月 11 日

您想建立或重新設計網站,您可能已選定幾個核心顏色,並考慮如何根據這些顏色快速實作主題。

您需要主色,以及動作、懸停狀態、錯誤的顏色,還有其他使用者介面所需的顏色。那麼淺色和深色模式選項呢?突然之間,您會發現自己需要許多顏色,這可能會讓人感到不知所措。

好消息是,在建構與定義網站的顏色權杖相關的調色盤,以及在顏色模式之間切換時,Baseline 功能可以為您完成許多繁重的工作。您可以在精選的示範中探索其中幾項技術,也就是虛構的 Baseline Radio 網站上以顏色為主題的播放清單。

以相對顏色為基礎建構

如果您對主題的主要顏色有想法,只要具備一些基本色彩理論和 CSS 相對顏色語法,就能快速開始產生要在主題中使用的調色盤。

假設你的基底色是藍綠色,你可以先定義偏好的顏色格式。接著,您可以使用任何色彩函式,根據基底顏色建立新顏色:

html {
  --base-color: oklch(43.7% 0.075 224);
}

--base-color 自訂屬性是使用 oklch() 顏色函式建立。OkLCh 是 Oklab 色域的圓柱形式,可定義三個管道的值:L (亮度)、C (色度)、H (色調),以及用於控制透明度的選用 Alpha 管道。

OkLCh 是這類顏色操控的合適格式,因為它旨在提供感知均勻性。舉例來說,如果只調整色彩的色調,產生的顏色應該與原始顏色有相似的感知亮度與色度。這項功能特別有助於避免發生非預期的對比問題。

--base-color 保持相同的明度和色度,您可以在兩個方向調整色調 120 度,即可獲得三元色調色盤。

html {
  /* ... */
  --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  --triadic-color-secondary: oklch(from var(--base-color) l c calc(h - 120));
}

如圖所示,相對顏色語法會使用顏色函式,透過 from 關鍵字參照原始顏色 (本例中為 --base-color),並根據所選輸出顏色調整顏色空間的個別管道,在本例中,輸出顏色也會是 OkLCh。

產生的輸出內容會提供 --accent-color 的深粉紅色,以及用於 --highlight-color 的金色色調,兩者都與原始 --base-color 的明度和色度相同。

html {
  /* ... */
  --accent-color: var(--triadic-color-primary);
  --highlight-color: var(--triadic-color-secondary);
}

  html {
    /* Input color in the rgb color space*/
    --base-color: teal;

     /* Output color in oklch. Computes to oklch(0.543123 0.0927099 314.769) */
     --triadic-color-primary: oklch(from var(--base-color) l c calc(h + 120));
  }

互補色會將色調角度增加 180 度。

html {
  /* ... */
  --complement-color: oklch(from var(--base-color) l c calc(h + 180));
  --border-highlight: var(--complement-color);
}

在 UI 的懸停狀態中,您可能想輸出特定顏色的較淺版本。也就是提高明度通道的值。如果是有效狀態,您可能想調整 Alpha 通道來新增透明度,或是降低亮度通道的值來調暗。

html {
  /* Darken the --base-color by 15% */
  --base-color-darkened: oklch(from var(--base-color) calc(l * 0.85) c h);
  /* Assign this color a meaningful variable name */
  --action-color: var(--base-color-darkened);
  /* Lighten the --action-color by 15% */
  --action-color-light: oklch(from var(--action-color) calc(l * 1.15) c h);
  /* Darken the --action-color by 10% */
  --action-color-dark: oklch(from var(--action-color) calc(l * 0.9) c h);
}

在這裡,我們是從 --base-color 衍生 --action-color,並用於按鈕和連結。--action-color 有淺色和深色兩種變體,即使 --action-color 相對的顏色並非 --base-color,這兩種變體仍會套用。

你可以使用 calc() 等數學函式調整管道,或以新值完全取代管道。未變更的管道會以各自的字母表示 (例如,未變更的明度值會以 l 表示)。

使用 color-mix() 混合顏色

如要使用其他顏色變體,可以採取類似做法,並調整 --base-color 自訂屬性的其他管道。或者,您也可以使用 color-mix(),在設計的其他方面加入基底色的提示。

--border-color 是底色和命名顏色 grey 的混合色,在 oklab 色域中經過插補。當做顏色插補方法使用時,這會提供感知上一致的結果。

html {
  --base-mix-grey-50: color-mix(in oklab, var(--base-color), grey);
  --border-color: var(--base-mix-grey-50);
}

預設值為各 50%,但您可以調整百分比權重,讓其中一種顏色更顯眼。

html {
  --background-mix-base-80: color-mix(in oklab,
    var(--background-color) 80%,
    var(--base-color));
  --surface-light: var(--background-mix-base-80);
}

如要為元素新增更多顏色,也可以使用相對顏色語法調整色度通道。聯絡人表單中的文字輸入欄位在焦點狀態下,邊框會稍微鮮豔一些。

[data-input*="text"] {
  --focus-ring: transparent;
  /* ... */
  &:focus {
    --focus-ring: oklch(from var(--border-color) l calc(c + 0.1) h);
  }
}

選擇啟用淺色和深色模式

有了可使用的顏色組合後,您會希望有效率地為淺色和深色模式套用不同顏色。

使用 color-scheme 屬性支援淺色和深色主題的信號

您可以使用 color-scheme 屬性,立即告知瀏覽器您的網站可使用「淺色」、「深色」或兩種模式。這項屬性會告知瀏覽器,元素可在哪些色彩配置中順利算繪。

 html {
   color-scheme: light dark;
}

:root 虛擬元素或 html 元素上設定 color-scheme: light dark

  • 告知瀏覽器您的網頁支援淺色或深色模式。
  • 變更瀏覽器使用者介面的預設顏色,以符合相應的作業系統設定。

如要提早通知使用者代理程式網頁支援淺色和深色模式,您也可以在文件的 <head> 中新增 <meta> 元素,表示支援色彩配置切換。

<head>
  <!-- ... -->
   <meta name="color-scheme" content="light dark">
</head>

使用 light-dark() 函式設定「淺色」和「深色」變體

身為作者,您可能習慣使用 prefers-color-scheme @media 查詢設定網頁顏色。

@media (prefers-color-scheme: light) {
  html {
    --background-color: oklch(95.5% 0 162);
    --text-color: black;
  }
}

@media (prefers-color-scheme: dark) {
  html {
    --background-color: oklch(22.635% 0.01351 291.83);
    --text-color: white;
  }
}

這項功能非常適合用於作者控制的顏色和樣式,但如上一節所述,您仍須使用 color-scheme 更新瀏覽器 UI 的顏色。

使用 prefers-color-scheme 查詢變更網頁顏色也表示部分程式碼會重複,因為您必須分別定義每個模式的顏色。

不過,如果是在整個網頁 (或特定元素) 上設定 color-scheme,您可以使用 light-dark() 函式,在一行程式碼中為每個模式設定顏色。

這個函式接受兩種顏色。第一個用於色彩配置設為「淺色」時,第二個則用於色彩配置設為「深色」時。

html {
  color-scheme: light dark;
  /* Color custom property values for both light and dark modes */
  --base-color: light-dark(oklch(43.7% 0.075 224), oklch(89.2% 0.069 224));
  --background-color: light-dark(oklch(95.5% 0 162), oklch(22.635% 0.01351 291.83));
  --accent-color: oklch(from var(--base-color) l c calc(h + 120));
  --active-color: light-dark(var(--action-color-light), var(--action-color-dark));
  /* ... */
}

與任何自訂屬性一樣,您可以在全域或特定元件中設定顏色 light-dark(),然後視需要用於其他位置。

/* custom property usage */
body {
  background-color: var(--background-color);
  /* ... */
}

:any-link {
  /* ... */
  text-decoration-color: var(--accent-color);
}

透過內建主題切換器賦予使用者控制權

主題能配合使用者的預設系統或瀏覽器顏色偏好設定,這當然很棒,但您還可以進一步讓網站訪客覆寫這些預設顏色偏好設定。

如果您建立主題切換按鈕,更新 <html> 元素上的 data-scheme 屬性,可以使用相同的屬性,透過 CSS 變更 color-scheme

html {
  color-scheme: light dark;

  &[data-scheme="light"] {
    color-scheme: light;
  }

  &[data-scheme="dark"] {
    color-scheme: dark;
  }

  &[data-scheme="green"] {
      --base-color-light: oklch(48.052% 0.11875 151.945);
      --base-color-dark: oklch(92.124% 0.13356 151.558);
      color-scheme: light dark;
   }
}

data-scheme="light"data-scheme="dark" 只會以各自的色彩模式顯示網頁。data-scheme="green",兩種模式皆可查看,且 --base-color 會變更為綠色,由於大多數其他顏色都是以 --base-color 為基礎,因此會產生全新的調色盤。

使用 @property 註冊自訂屬性

目前為止,示範中的顏色都已設為標準自訂屬性。您也可以使用 @property 規則註冊屬性,享受型別檢查帶來的好處。

由於介面中的許多其他顏色都以 --base-color 為基礎,因此最好確保 --base-color 一律為顏色,且具有備用值。

@property --base-color-light {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(43.7% 0.075 224);
}

@property --base-color-dark {
  syntax: '<color>';
  inherits: false;
  initial-value: oklch(89.2% 0.069 224);
}

html {
  --base-color: light-dark(var(--base-color-light), var(--base-color-dark));
}

這樣一來,如果 --base-color 不慎變更為無效值,系統一律會根據 @property 規則,將其還原為 initial-value

以這種方式註冊特定屬性,也能在 linear-gradient() 中順暢地為顏色製作動畫。

.main-heading {
  background: linear-gradient(in oklch 90deg, var(--text-color) 50%, oklch(from var(--base-color) l c var(--header-hue)));
  background-clip: text;
  color: transparent;
  animation: header-hue-switch 5s ease-in-out infinite alternate;
}

.main-heading 具有 linear-gradient() 背景,可透過 background-clip 屬性的透明文字顯示。

部分文字會顯示 hue,使用相對顏色語法從 26.67 的管道值動畫化為 277

@keyframes header-hue-switch {
  from {
    --header-hue: 26.67;
  }

  to {
    --header-hue: 277;
  }
}

註冊 --header-hue 自訂屬性後,瀏覽器就會知道這個自訂屬性是數字,因此動畫可以順暢播放。

@property --header-hue {
  syntax: '<number>';
  inherits: false;
  initial-value: 100;
}

如果自訂屬性未註冊,瀏覽器就不知道 --header-hue 的資料類型,因此轉換為數字時會是離散動畫,也就是在狀態之間跳轉,不會逐步插補。

總結

有了全新的 Baseline 工具,您就能快速建構可調整的調色盤,並更有效率地建立顏色變數。不過,你還是得自己從無數的顏色選項和組合中做出選擇。

這樣動態建立調色盤可提供彈性。如要變更品牌的基本顏色,只要更新 --base-color,其餘主題就會隨之變更。或者,如果您新增音樂播放功能,可以決定要動態變更基底顏色,以配合目前播放的歌曲。

抵免額

主題切換器邏輯改編自 Adam Argyle 的主題切換元件