色彩系統正在從 HSL/RGB 換血到 OKLCH,而對比檢驗也正在從 WCAG 2.1 的相對亮度公式,轉向更貼近人眼感知的 APCA(Advanced Perceptual Contrast Algorithm)。這波換血不是美學偏好,而是設計 token 基礎建設的升級:OKLCH 讓「同一組色階在深色模式、多品牌主題下都維持一致亮度感」變得可預測,不再靠肉眼微調。APCA 則解決了 WCAG 2.1 長年被詬病的問題——同樣的對比比值,小字看得清楚、大粗體卻可能糊成一片,APCA 把字級與字重都算進去,判斷更貼近實際閱讀經驗。2026 年最務實的做法不是二選一,而是雙層測試:WCAG 2 當作合規底線,APCA 當作可讀性的天花板目標。這篇就整理這兩件事怎麼一起落地到設計系統與 design tokens 裡。
📖 學(核心)
為什麼 HSL/RGB 不夠用了:OKLCH 的感知均勻性
HSL 表面上直覺(色相、飽和度、亮度三個滑桿),但它不是「感知均勻」的色彩空間——同樣調高亮度數值,黃色看起來會比藍色亮很多,導致設計師必須每個色相都手動微調才能讓色階「看起來」一致。OKLCH(Oklab 色彩空間的圓柱座標版本)則是針對人眼感知校正過的模型,同一個 Lightness 數值,不同色相之間的視覺亮度差異大幅縮小。這代表設計團隊可以用同一套公式,批次生成整組色階(50~950 這種階層),不必逐色手調,深色模式也能透過單純調整 Lightness 產生對應的深色版本,而不是重新設計一套顏色。對多品牌、多主題的產品(例如同一套元件庫要套用在好幾個子品牌上)來說,這個「數學上可預測」的特性,直接省下大量微調時間。
APCA:比 WCAG 2.1 更貼近人眼的對比演算法
WCAG 2.1 的對比公式只看兩個顏色的相對亮度比值,例如「4.5:1」,完全不管文字大小或字重。這造成一個實務上的怪象:很小的深灰色字踩過 4.5:1 門檻就算合格,但讀起來還是吃力;反過來,某些對比稍低的大粗體標題明明很好讀,卻被判定不合格。APCA 把字級、字重都納入計算,分數會隨著文字用途(小內文 vs 大標題)動態調整門檻,更接近真實閱讀感受。目前 APCA 仍是 WCAG 3.0 草案中的「探索性」候選方案,並未成為正式規範——業界預期 WCAG 3.0 要到 2028~2030 年才會真正定案,但這不代表現在可以忽略它。
兩層測試策略:WCAG 2 當底線,APCA 當天花板
既然 APCA 還沒正式取代 WCAG 2.1,2026 年設計系統團隊普遍採用的做法是「雙軌並行」:法規合規面持續守住 WCAG 2.1 的 4.5:1 / 3:1 門檻,確保不會有法律風險;但在實際設計與開發階段,額外用 APCA 分數去把關文字的真實可讀性,尤其是淺色主題、灰階文字這類 WCAG 2.1 容易「假合格」的情境。這樣做的好處是,等到 WCAG 3.0 真正定案時,設計系統已經提前把 APCA 的思維內化進色彩 token,轉換成本會小很多。像 betterLCH 這類工具,已經把 OKLCH 的色階生成與 APCA 對比檢驗整合在同一套流程裡,讓設計師在挑色的當下就能同時看到兩種分數。
Design Tokens 如何把顏色系統跨平台落地
顏色系統再漂亮,如果沒辦法穩定同步到 iOS、Android、Web、Flutter 各個平台,對產品團隊來說就只是一份好看的規範文件。DTCG(Design Tokens Community Group)規範正是在處理這個問題:它定義了一套通用的 token 結構,讓顏色可以用 OKLCH、Display P3 這類現代色彩空間描述,同時支援多主題(淺色/深色)、多品牌的變體切換,再透過工具鏈自動產生各平台可用的程式碼。換句話說,設計師在 Figma 裡調的是一組 OKLCH 數值與語意化的 token 名稱(例如 color.text.primary),背後會自動轉譯成每個平台看得懂的格式,同時也能批次跑 APCA 檢驗,確保換膚、換品牌時對比不會悄悄跌破標準。
🧠 記
- OKLCH 是感知均勻的色彩空間,同一亮度數值在不同色相間視覺亮度更一致,比 HSL 更適合批次生成色階。
- 深色模式可以透過單純調整 OKLCH 的 Lightness 數值產生,不必整組色盤重新設計。
- APCA 把文字大小與字重納入對比計算,比 WCAG 2.1 的固定比值更貼近真實閱讀感受。
- APCA 目前仍是 WCAG 3.0 草案中的探索性方案,尚未成為正式規範,WCAG 3.0 定案預估落在 2028~2030 年。
- 2026 年務實作法是雙層測試:WCAG 2.1 當合規底線,APCA 當可讀性天花板。
- DTCG 規範讓顏色 token 支援 OKLCH、Display P3 等現代色彩空間,並可跨 iOS / Android / Web / Flutter 自動生成程式碼。
- 多品牌、多主題產品特別受益於 OKLCH + design tokens 的組合,因為色階生成與對比檢驗都能自動化、可預測。
✍️ 實踐
- 挑一個現有專案的主色階,用 OKLCH 重新定義 Lightness 階層(例如 50~900),對照原本 HSL 版本看視覺一致性差異。
- 用線上工具(例如 betterLCH 或瀏覽器 DevTools 的顏色選擇器)把目前介面的文字顏色轉成 OKLCH,記錄下 Lightness 數值。
- 針對站內最小字級的內文,同時跑一次 WCAG 2.1 對比比值與 APCA 分數,比較兩者判定是否一致。
- 找出「WCAG 2.1 剛好合格但讀起來吃力」的顏色組合(通常是淺色背景配中灰文字),用 APCA 分數重新調整。
- 如果專案有多品牌或多主題需求,盤點目前顏色是否用「語意化 token」定義(如
color.text.primary),而不是寫死的色碼。 - 把「WCAG 2.1 為底線、APCA 為目標」的雙層測試原則寫進團隊的設計系統文件,作為往後色彩審核的檢查清單。
🔗 延伸學習
- Exploring the OKLCH ecosystem and its tools — Evil Martians
- From HSL to OKLCH and betterLCH: predictable chroma and precise contrast for design systems
- WCAG3 Contrast as of April 2026 — Adrian Roselli
- Design Systems in 2026: Scale UI Without the Chaos
💬 問 AI
我正在維護一套設計系統的色彩 token,目前用的是 {HSL 或 RGB} 定義色階。
請幫我:
1. 把 {指定色相,例如主色 #3B82F6} 轉換成 OKLCH,並生成一組從淺到深、感知均勻的色階(例如 50~900)。
2. 針對 {指定情境,例如淺色背景配中灰內文字} 這組顏色,分別算出 WCAG 2.1 對比比值與 APCA 分數,告訴我兩者判定是否一致。
3. 如果不一致,建議一組同時滿足 WCAG 2.1 合規門檻、又符合 APCA 可讀性標準的替代顏色。
4. 幫我把這組顏色整理成語意化的 design token 命名建議(例如 color.text.primary、color.bg.surface),方便之後套用在 {我的產品名稱} 的多主題架構上。