
CSS color-mix() 與 OKLCH:從品牌色產生互動配色與備援值
品牌色只是介面配色的起點。滑鼠懸停、按下、停用、背景與框線,都需要彼此相關的顏色。CSS 的 color-mix() 與 OKLCH 可以把這些關係寫成共用公式。
但「能算出顏色」與「文字可讀、狀態清楚」是兩件事。本文以兩色混合和 CSS 自訂屬性為範圍,搭配淺色、深色主題及備援值的驗證方式。
日文原文發布: 2026-04-23
sRGB、HSL 與 OKLCH 描述的事情不同
sRGB 是網頁常用的 RGB 色彩空間;HSL 以色相、飽和度和明度描述 RGB 顏色,但相同 HSL 明度不代表看起來一樣亮。
例如 hsl(60 100% 50%) 和 hsl(240 100% 50%) 的 HSL 明度相同,相對亮度卻差很多。HSL 明度由 RGB 最大與最小分量計算,並不是知覺均勻的尺度。
CIELAB 與 Oklab 試圖讓色彩差異更貼近人類知覺。Björn Ottosson 在 2020 年發表 Oklab,OKLCH 是它的極座標表示法。知覺均勻性仍是近似,不能保證所有顏色與觀看條件都完全一致。
讀懂 OKLCH 的 L、C、H
- L(明度):常以 0 到 1,或百分比表示。
- C(彩度):0 表示無彩色。常見的 0.4 並不是規格上限;可顯示範圍取決於明度、色相及目標色域。
- H(色相):色相圓上的角度,通常以度數表示。
oklch(62.3% 0.214 259.815)
oklch(0.623 0.214 259.815)這兩種寫法表示同一個顏色,也是 Tailwind CSS v4 的 blue-500 定義。Oklab 的設計目標包含改善藍色區域的知覺表現,也能描述超出 sRGB 的顏色,但不代表每台螢幕都能完整顯示任意 OKLCH 值。
保持 L 一致,有助於協調不同色相的明度;不過,OKLCH 的 L 不是 WCAG 相對亮度。與實際背景的對比值仍要另外計算。
混色空間、比例與色相路徑
以下範例指定色彩空間與兩個顏色。省略百分比、比例正規化及 alpha 都會影響結果:
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。在極座標色彩空間中,shorter hue、longer hue 等選項會改變色相的插值路徑。使用 OKLCH 並不保證每次混色都符合設計意圖,也不保證中間色一定鮮豔。
混入透明色會改變 alpha,實際看到的顏色還取決於背景合成。超出顯示色域的值也可能經過色域對應,因此應查看最終呈現結果,而不是只憑語法判斷。
從一個品牌色產生多種狀態
先定義品牌色,再讓各種狀態引用同一個輸入:
: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); }改變 --brand,其他顏色就會依同一套關係更新。這是產生配色的範例,不是已通過無障礙檢查的完整色票。若按鈕使用白字,讓懸停背景變亮,可能反而降低文字對比。
焦點指示與框線也要和實際相鄰顏色一起檢查。停用控制項雖有 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 開始。相對色彩語法及更新的擴充功能必須另查,這些版本也不能直接換算成讀者的支援比例。
CSS 自訂屬性可以保留含有未支援函式的值。先寫靜態值、再用同名變數覆蓋,未必能在計算值失效時退回舊值。應把更新放在功能檢測內:
: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 的內建色票也需要實際驗證
Tailwind CSS v4 官方色彩定義採用 OKLCH,例如 --color-blue-500: oklch(62.3% 0.214 259.815)。不應把 v3 的整套預設色票一概描述為以 HSL 為基礎。
即使用內建色票,也要檢查實際的前景、背景與狀態組合。採用 OKLCH 不會自動保證廣色域輸出或無障礙符合性。
建議的配色工作流程
- 以 OKLCH 定義品牌色,或先轉換已知的 HEX 顏色。
- 用
color-mix()表達候選衍生色。 - 在適合時維持相近明度,但不要把 L 當成對比值。
- 針對一般文字的 WCAG AA,依適用條件及例外檢查 4.5:1。
- 分別選定淺色、深色主題的基本色,驗證全部配對。
- 提供靜態備援值,再於
@supports內更新自訂屬性。 - 用
--text-muted、--brand-hover等用途命名,讓設計意圖可被檢查。
產生配色和驗證配色應在同一個流程中完成。新語法或常用色票,都不能取代實際介面的檢查。
重點整理
- OKLCH 以近似知覺模型描述明度、彩度和色相。
- color-mix() 能共用衍生色公式,但不保證對比值合格。
- 分別檢查比例、色相路徑、alpha、背景與色域。
- 自訂屬性的備援更新應放在 @supports 內。
- 區分基本語法與擴充功能,並驗證淺色和深色主題。
參考資料與來源
編輯說明
本文使用 AI 協助編輯,並於發布前由編輯確認。內容仍可能包含事實、解讀或時效上的錯誤;進行重要判斷前,請查閱所列的一手資料或官方文件。

