UrsaKit 封面圖:兩塊色票與 WCAG 的 4.5:1、3:1 對比門檻

對比度是設計師最容易感受到的無障礙問題,因為失敗看得見:白卡片上的灰字,四十歲以上的人根本讀不了。WCAG 把這個判斷變成一個數字,而這個數字有精確定義,不是憑感覺抓的經驗法則。

公式很短,卻很容易用錯:色彩選擇器給你的是十六進位值,不是亮度;調色盤裡看起來相鄰的兩種灰,可能剛好落在 4.5:1 的兩側。本文說明定義、門檻,以及那些大家最常漏掉的檢查。

01對比度到底在量什麼

WCAG 把對比度定義為 (L1 + 0.05) / (L2 + 0.05),L1 是較亮顏色的相對亮度,L2 是較暗的。這個比值從兩個相同顏色的 1:1,一路到黑與白的 21:1。

真正的工作量在相對亮度。對 sRGB,WCAG 把它定義為三個通道的加權和:

L = 0.2126 * R + 0.7152 * G + 0.0722 * B

RsRGB = R8bit / 255
if RsRGB <= 0.04045 then R = RsRGB / 12.92
else R = ((RsRGB + 0.055) / 1.055) ^ 2.4

G 與 B 用同樣的線性化。指數 2.4 是權重會有意義的原因:sRGB 原始值經過 gamma 編碼,所以中灰的位元組值不是白色亮度的一半。綠色權重最大,這也是為什麼黃色對黑色可以到 19.56:1,而藍色怎麼調都很吃力。

那個 0.05 不是隨手加的補償。它讓極暗顏色的比值保持有限,也符合公式在黑色附近的行為。自己重寫這段公式沒問題,但請用更新後的 0.04045 門檻:舊版 WCAG 文件用的是 0.03928,規範的註記說明它在 2021 年 5 月被更新。

對比度是在量兩個實際呈現的顏色。

WCAG 說明:沒有指定背景色時以白色為準,而且量測時可以關閉反鋸齒。真實頁面會先把漸變、圖片與透明度合成,才畫上文字,所以要量用戶真正看到的像素。

02你必須達到的門檻

一般頁面上幾乎所有對比決策,都由三條成功準則涵蓋:

準則等級要求
1.4.3 Contrast (Minimum)AA一般文字 4.5:1,大字 3:1
1.4.6 Contrast (Enhanced)AAA一般文字 7:1,大字 4.5:1
1.4.11 Non-text ContrastAA介面元件與必要圖形 3:1

三條準則的豁免條件相同:logo 或品牌名稱中的文字、純裝飾文字、任何人都不會看到的文字,以及停用中用戶介面元件裡的文字。最後一項比想像中窄:停用的按鈕豁免,但一個剛好放在淺色面板上的普通標籤不豁免。

WCAG 2.2 在顏色章節之外又加了一條。2.4.13 Focus Appearance 屬於 AAA,要求元件在取得焦點與未取得焦點時,同一批像素之間至少有 3:1 的對比。如果你的焦點框只是與背景相近的淡光暈,你看得見,數字看不見。

03實例:一個十六進位位元就決定結果

以下數值是在 2026-10-04 用上述 WCAG 公式、以 Python 3 算出來的,都是最常被爭論的組合:

前景色背景色對比AA 一般文字AA 大字
#000000#ffffff21.00:1通過通過
#1f2937#ffffff14.68:1通過通過
#2563eb#ffffff5.17:1通過通過
#767676#ffffff4.54:1通過通過
#777777#ffffff4.48:1未通過通過
#3b82f6#ffffff3.68:1未通過通過
#9ca3af#ffffff2.54:1未通過未通過

其中兩列值得記住。#767676 是白底上仍能通過 AA 的經典最淺灰色,#777777 是只差一個十六進位位元、卻已經不合格的鄰居。#3b82f6 是常見的品牌藍,用在標題與大字可以過 AA,用在正文就不行。

二十一比一是上限,所以黑底白字不會「多餘的安全」而能折抵其他組合。每一對顏色各自計分,而且門檻是套用在實際呈現的文字上,包含字重與字級。

同一段計算用 Python 寫出來,以及它印出的結果:

def lum(h):
    c = [int(h[i:i+2], 16) / 255 for i in (1, 3, 5)]
    f = lambda v: v / 12.92 if v <= 0.04045 else ((v + 0.055) / 1.055) ** 2.4
    r, g, b = map(f, c)
    return 0.2126 * r + 0.7152 * g + 0.0722 * b

def ratio(a, b):
    hi, lo = sorted([lum(a), lum(b)], reverse=True)
    return (hi + 0.05) / (lo + 0.05)

for c in ('#767676', '#777777'):
    print(c, round(ratio(c, '#ffffff'), 2))
#767676 4.54
#777777 4.48

04在瀏覽器裡檢查一組顏色

UrsaKit 的 顏色對比檢查工具 實作了上面那條公式,並一次回報所有門檻。

  1. 在第一個欄位輸入或選取 Text colour(文字色)。它接受 3 或 6 位數的十六進位值,預設是 #1f2937。
  2. 在第二個欄位輸入 Background colour(背景色),預設是 #ffffff。
  3. 想對調兩色時按 Swap,不必重新輸入。
  4. 讀 Contrast ratio,再看四項檢查:AA 一般文字 4.5:1、AA 大字 3:1、AAA 一般文字 7:1、AAA 大字 4.5:1。
  5. 看預覽區,同一組顏色會以標題與 16px 內文各呈現一次。

預覽之所以重要,是因為比值不等於易讀性。筆畫細、字重輕的字體,看起來會比數字更糟,WCAG 自己的定義也註明筆畫極細的字體在低對比下更難閱讀。工具告訴你這組顏色符不符合規範,預覽告訴你好不好讀。

如果你要修的是整個 theme 而不只是一組顏色,請在 CSS 測試工具 裡改動 token 再重新檢查實際呈現結果。只單獨測變數會漏掉合成後的情況:卡片背景疊在頁面背景上,文字又疊在卡片上。

05什麼算大字

大字可以用較寬鬆的門檻,因為較大的字形不需要那麼高的對比就能閱讀。WCAG 把大字定義為至少 18 點,或粗體 14 點,或是對中日韓字體能達到等效大小的字級。

這些單位是排版用的點,不是 CSS 像素。以 CSS 的每英寸 96 像素換算,18 點是 24 像素,14 點約是 18.67 像素。所以 20px 的粗體標題算大字,同樣字級但沒有加粗就不算。

中日韓條款是最常被翻譯漏掉的部分。一個 16px 的中文標題,在純拉丁字母的設計裡可能被歸為一般文字,但準則明確保留了「讓中日韓字形可讀的等效大小」的空間,而不是硬套點數。

用兩個 token,不要一個打到底。

單一淡灰色通常沒辦法同時滿足正文與小字。為正文定義一個能過 4.5:1 的 token,再為註釋定義另一個更深的,然後拿兩者去對比調色盤裡的每一種表面色。

06非文字對比:圖標、邊框與焦點框

1.4.11 準則把這個概念延伸到文字之外。辨識用戶介面元件或其狀態所需的視覺資訊,以及理解內容所必需的圖形部分,都需要與相鄰顏色有 3:1 的對比。

實務上這涵蓋:當邊框是唯一能看出欄位起始位置的線索時,輸入框的邊框;開與關的切換狀態差異;圖表中承載意義的線條輪廓;以及可用鍵盤操作的元件上的焦點指示。裝飾性元素,或外觀完全由瀏覽器決定、作者沒有改過的元件,不在範圍內。

placeholder 文字是常見的犧牲品。只過 3:1 的淡灰 placeholder 常被誤判為合格,但 placeholder 是文字,文字就受 1.4.3 管。如果 placeholder 是欄位唯一的標籤,它就需要與輸入框背景達到完整的 4.5:1。

07常見錯誤

症狀原因修正
筆電上看起來沒問題,投影機上完全讀不到量錯了背景拿文字可能出現的最深表面色來量
hover 狀態掉到 AA 以下只檢查了預設狀態預設、hover、focus、active、visited 都要檢查
半透明遮罩上的文字不合格計算時忽略了 alpha先合成顏色,再量合成後的結果
深色模式標題過關,正文卻不過同一個 token 用在兩種字級讓正文有自己的 token,並留更大餘裕
行內連結消失在段落裡只靠顏色承載意義對比之外再加上底線或其他非顏色線索
圖表各系列分不出來線條與繪圖區的對比低於 3:1提高對比,或加上直接標註與樣式區隔

08資料來源

常見問題

WCAG 要求的對比度是多少?

AA 等級要求一般文字 4.5:1、大字 3:1;AAA 等級提高到 7:1 與 4.5:1。圖標、輸入框邊框這類非文字元素,依 1.4.11 準則需要 3:1。

對比度是怎麼算出來的?

WCAG 定義為 (L1 + 0.05) / (L2 + 0.05),L1 是較亮顏色的相對亮度,L2 是較暗的。相對亮度是 sRGB 三通道線性化後的加權和:0.2126 R + 0.7152 G + 0.0722 B。

WCAG 裡的大字定義是什麼?

至少 18 點,或粗體 14 點,或是對中日韓字體能達到等效大小的字級。以 CSS 的每英寸 96 像素換算,18 點是 24 像素,14 點約為 18.67 像素。

為什麼 #767676 過關,#777777 卻沒過?

在白色背景上,#767676 量到 4.54:1,#777777 是 4.48:1。AA 門檻是 4.5:1,所以只差一個十六進位位元就決定了結果。灰色一定要量,不能憑眼睛看。

Logo 與停用按鈕也需要對比度嗎?

不用。WCAG 豁免 logo 或品牌名稱中的文字、純裝飾文字、任何人都不會看到的文字,以及停用中的用戶介面元件裡的文字。只要是用戶預期要閱讀的內容,都在規範範圍內。

非文字對比 3:1 是在管什麼?

它管的是辨識介面元件及其狀態所需的視覺資訊,以及理解內容所必需的圖形部分。輸入框邊框、開關狀態、焦點框與圖表線條都是典型例子。

透明度也算進對比計算嗎?

實際上算。半透明顏色會與底下的顏色合成,而用戶看到的就是合成後的顏色。請量測最終呈現的那一對顏色,而不是宣告的 alpha 值。

返回文章列表

相關文章

相關工具