
CSS color-mix() 與 OKLCH:由品牌色建立按鈕及深色模式配色
品牌色改了,按鈕停留色、邊框和背景能否一併更新?color-mix() 配合 CSS 變數,可以把衍生顏色寫成公式;OKLCH 則提供較貼近視覺明度的操作方式。
這些功能有助整理配色,但計算出顏色不等於已符合對比度要求。本文示範兩色混合與深淺模式設定,並說明需要另外檢查的顯示和兼容性條件。
日文原文發布: 2026-04-23
sRGB、HSL 與 OKLCH 有何不同?
sRGB 是網頁常用的 RGB 色彩空間。HSL 以色相、飽和度和明度操作 RGB 顏色,但相同的 HSL L 值不代表相同的視覺明度。
例如 hsl(60 100% 50%) 與 hsl(240 100% 50%) 都是 L = 50%,相對亮度卻很不同。HSL 的 L 由 RGB 最大及最小分量決定,並非按視覺等距設計。
CIELAB 和 Oklab 嘗試讓色差更易按知覺處理。Björn Ottosson 在 2020 年發表 Oklab;OKLCH 是其極座標形式。知覺均勻性仍然是近似,不是所有顏色和觀看環境都完全一致。
L、C、H 分別控制甚麼?
Oklab 原文說明其設計,包括改善藍色範圍等知覺表現。OKLCH 可表示 P3 等色域的顏色,但不代表每個值都能在每塊屏幕原樣顯示。
- L(Lightness):0 至 1,表示知覺明度。
- C(Chroma):色度;0 是無彩色。0.4 不是規格上限,可顯示範圍取決於 L、H 及目標色域。
- H(Hue):以角度表示色相,通常寫成 0 至 360 度。
/* Tailwind CSS v4 的 blue-500 */
oklch(62.3% 0.214 259.815)
oklch(0.623 0.214 259.815) /* 相同的小數表示 */相同 L 值的不同色相,通常有較接近的知覺明度,適合建立同系列配色。不過 OKLCH 的 L 並非 WCAG 的相對亮度;即使 L 相同,也要另算文字與背景的對比度。
color-mix() 的比例、路徑及透明度
以下使用指定色彩空間及兩種顏色的語法:
color-mix(in srgb, red 50%, blue)
color-mix(in oklch, #2563eb 80%, white)
color-mix(in oklch, #2563eb, black 30%)
color-mix(in oklch longer hue, red, blue)前三個例子分別是 50:50、80:20、70:30。省略比例時有補足規則;總和不是 100% 時,正規化及 alpha 的處理也會影響結果。
在帶色相的空間,shorter hue 和 longer hue 會選取不同路徑。使用 OKLCH 不保證一定得到預期色彩,也不保證混色不會接近灰色。
與透明色混合會改變 alpha,最後看到的顏色還受背景合成影響。若超出輸出色域,也可能經過色域映射,因此要在實際顯示環境檢查。
由一個品牌色建立介面狀態
以 --brand: #2563eb 為基礎,分別定義滑鼠停留、按下、停用、邊框及背景色:
:root {
--brand: #2563eb;
/* 互動狀態 */
--brand-hover: color-mix(in oklch, var(--brand), white 15%);
--brand-active: color-mix(in oklch, var(--brand), black 15%);
--brand-disabled: color-mix(in oklch, var(--brand), transparent 60%);
/* 邊框、背景及焦點的候選顏色 */
--brand-border: color-mix(in oklch, var(--brand), white 70%);
--brand-bg: color-mix(in oklch, var(--brand), white 92%);
--brand-focus: color-mix(in oklch, var(--brand), transparent 70%);
}
.button {
background: var(--brand);
border: 1px solid var(--brand-border);
}
.button:hover { background: var(--brand-hover); }
.button:active { background: var(--brand-active); }
.button:disabled { background: var(--brand-disabled); }把品牌色改為紅色,衍生顏色便會跟隨公式更新,毋須逐個修改色碼。
這是一組產生候選顏色的公式,不是已驗證的完整色板。白色文字配停留色、半透明焦點色及邊框,都要放在實際背景上檢查。停用控制項雖有 WCAG 適用例外,仍應讓使用者辨認其狀態。
深淺模式共享衍生色公式
先為兩個模式選好文字、背景及重點色,再讓卡片等元件共用公式:
:root {
--text: #1f2937;
--bg: #ffffff;
--accent: #2563eb;
}
[data-theme="dark"] {
--text: #e5e7eb;
--bg: #111827;
/* 深色模式另選較亮的重點色 */
--accent: color-mix(in oklch, #60a5fa, transparent 0%);
}
.card {
background: color-mix(in oklch, var(--bg), var(--accent) 5%);
border-color: color-mix(in oklch, var(--text), transparent 85%);
}這種做法把模式差異集中在幾個基本色,而衍生色定義可以共用。示例中的 transparent 0% 保留原本的重點色,並不是反轉明度的運算。
深色模式的重點色是另外選定的。兩個模式都需要逐一檢查文字、卡片、邊框及互動狀態與背景的組合。
用 @supports 分隔後備值
按 2026 年 9 月 5 日查核的 MDN 兼容數據,基本 oklch() 由 Chrome/Edge 111、Firefox 113、Safari 15.4 起支援;兩色 color-mix() 則由 Chrome/Edge 111、Firefox 113、Safari 16.2 起支援。相對顏色及其他新語法要另查,不能由最低版本推算整體市場覆蓋率。
自訂屬性可以保留含未支援函數的字串。先寫舊值、再寫新值,不一定能在使用變數時退回舊值;應在功能偵測成立時才更新:
:root { --brand-hover: #3b7ced; }
@supports (color: color-mix(in oklch, red, blue)) {
:root { --brand-hover: color-mix(in oklch, #2563eb, white 15%); }
}
.button:hover { background-color: var(--brand-hover); }靜態值是後備顏色,不保證與計算結果完全相同。舊環境檢查後備色,新環境檢查混色結果;功能偵測成功也不等於各瀏覽器的顯示毫無差異。
Tailwind CSS 的 OKLCH 色彩定義
Tailwind CSS v4 的官方顏色定義採用 OKLCH,例如 --color-blue-500: oklch(62.3% 0.214 259.815)。不能反過來把 v3 的標準色板一概描述成 HSL 色板。
採用框架內置色彩後,仍要檢查實際文字、背景及狀態組合。OKLCH 本身不會自動保證廣色域輸出或無障礙符合性。
把配色與驗證一起納入流程
- 以 OKLCH 定義品牌色,或由 HEX 轉換後檢查結果。
- 用
color-mix(in oklch, ...)建立衍生色。 - 以接近的 L 建立系列,但保留知覺均勻性只是近似的前提。
- 一般文字的 WCAG AA 要按適用條件達到至少 4.5:1,例外另行處理。
- 深淺模式分別設定基本色,並驗證所有衍生組合。
- 先定義靜態後備值,再於
@supports內使用混色。 - 用
--brand-hover、--text-muted等用途清楚的名稱管理設計變數。
重點整理
- OKLCH 以明度、色度及色相操作顏色,L 不等於 WCAG 相對亮度。
- color-mix() 讓衍生色公式共用,但不能保證對比度合格。
- 比例、色相路徑、alpha、背景及色域都會影響結果。
- 後備變數應以 @supports 與新語法分隔。
- 基本功能及擴展語法的兼容性分開查核,深淺模式都要測試。
參考資料及來源
編輯說明
本文使用 AI 協助編輯,並在發布前由編輯核對。內容仍可能包含事實、理解或時效上的錯誤;作出重要決定前,請查閱所列的一手資料或官方文件。

