雜記 › 資源分享 › 漸層底上的白字為什麼總看不清?把 WCAG 對比度逐個色標算一遍

漸層底上的白字為什麼總看不清?把 WCAG 對比度逐個色標算一遍

首屏主視覺區那版日落漸層是我照稿打的,兩端都好看,白字壓上去卻被回饋說副標題發虛。我先懷疑字級字重,後來才意識到:從 #ff512f 走到 #dd2476 的是整條線,驗收的人只看了好看的那端。把兩個色標分開當純色算,白字 0% 處 3.25:1、100% 處 4.58:1,差的那半檔全在開頭。

判據只有兩條線,卡的是最差那個色標

口徑按頁面原話:正文不低於 4.5:1,大號文字(24px 以上,或 18.66px 粗體)不低於 3:1,取最差色標同時判這兩檔;它是門檻,不是過了就人人可讀的保證。基準值:#000000 對 #ffffff 是 21.00:1 的理論上限,#767676 對白 4.54:1、#777777 對白 4.48:1,一檔灰就能翻邊,所以小數位我保持兩位。落日換黑字是 6.47:1 與 4.59:1,兩項都達標。

同一份漸層,六種輸出字串差在哪

只換格式,色標角度寫法都不動,在 CSS 漸層產生器 裡逐個切出來:

輸出格式得到的字串
background-image 單行background-image: linear-gradient(135deg, #ff512f 0%, #dd2476 100%);
background 簡寫background: linear-gradient(135deg, #ff512f 0%, #dd2476 100%);
多行縮排
background-image:
  linear-gradient(
    135deg,
    #ff512f 0%,
    #dd2476 100%
  );
行內 style<div style="background: linear-gradient(135deg, #ff512f 0%, #dd2476 100%)">
Tailwind 任意值class="bg-[linear-gradient(135deg,#ff512f_0%,#dd2476_100%)]"
CSS 變數
--gradient: linear-gradient(135deg, #ff512f 0%, #dd2476 100%);

background: var(--gradient);

只有 Tailwind 那行改了字元:逗號後不留空格、分隔空格換成底線。

逐色標算下來,淺色幾乎都要求換黑字

色板白字 0%白字 100%白字最差黑字最差
落日 135deg3.25:14.58:13.25:14.59:1
海洋 120deg12.55:11.91:11.91:1沒算過
薄荷 90deg1.59:11.34:11.34:113.18:1
霓虹 45deg6.28:13.72:13.72:13.35:1
  • 海洋白字 0% 處 12.55:1 還有餘裕,100% 處只剩 1.91:1;補一個中點節點後是 12.55 / 10.92 / 1.91,最差仍是 1.91。
  • 薄荷白字最差 1.34:1、黑字最差 13.18:1,淺底必須換黑字。
  • 霓虹白字最差 3.72:1、黑字最差 3.35:1,兩個方向都停在只夠大號文字那檔。

帶透明度的節點要先跟假設底色混合

漸隱綠是 #39ff14 從 1 漸變到 0,三種寫法三種字串:HEX 寫 linear-gradient(135deg, #39ff14 0%, #39ff1400 100%),rgb 寫 rgba(57,255,20,0),hsl 寫 hsla(111,100%,54%,0)。8 位 HEX 末兩位是 alpha:0.6 對應 99(0.6×255=153),0.5 對應 80,0.99 對應 fc;反過來 #aabbcc80 解析出的是 0.5019607843137255,不是剛好的 0.5,transparent 則是 alpha 0 的 #000000。寫法拿不準時我用 顏色格式互轉 核一遍。

alpha 小於 1 的節點先與假設底色(預設白)混合再算,底色一換結果就換:底色白時 0% 處 1.36:1、100% 處 1.00:1;底色換成 #0a0a0a 後 100% 處升到 19.80:1,0% 處仍是 1.36:1,最差還是 1.36——深底只救末端,救不了整條。頁面在這時還會提示:8 位 HEX 在 Safari 上要 9.1+,要照顧更舊環境就換成 rgb()。

報表裡沒有中段,量化是另一個坑

逐色標算的代價是:中點不在色標裡,就不會出現在報表裡。落日兩色按 sRGB 通道取算術平均,中點 #ee3b53 的白字是 3.90:1、黑字 5.39:1,比 0% 的 3.25 好一點,卻仍停在只夠大號文字那檔。發灰也是同一算法:海洋兩端 #1a2980 與 #26d0ce 的通道均值是 #207da7,深藍與亮青取平均就得到這種灰藍;想讓它被報出來,就像三段紫那樣把中間色直接寫進 50%。

量化這個坑:每通道 0-255 共 256 級,256 的三次方是 16777216 色;兩色鋪滿 1000px 寬時每級佔 3.9063px,約 4px 一檔,斜向 45deg 時漸層線被拉長約 1.4142 倍。落日兩色的通道差是 R 34 級、G 45 級、B 71 級。

幾個當時把我繞住的問題

Q:0deg 是朝上還是朝右?

朝上。CSS 的 0deg 指向正上方,數值順時針增大,90deg 是右、180deg 是下;數學極角的 90deg 指向上,兩套別混。角度框允許輸 -360 到 720,但輸出會歸一:-45 歸成 315、405 歸成 45、360 和 720 都歸成 0。

Q:conic 的百分比是距離嗎?什麼時候要勾後備純色?

是角度,100% 等於 360deg,彩虹環從 0% 鋪到 100% 繞一圈。規範裡有 repeating-conic-gradient 但沒有瀏覽器實作,頁面不提供。後備色也不是漸層本身的必須項,勾上只多一行 background-color: #ff512f;,取的是排序後第一個色標。我只在用 conic 時勾,它在 Safari 上要 12.1+,舊瀏覽器會讓整條宣告失效;用 linear 或 radial 時不勾,它改不了色標本身的對比度。

Q:色標位置亂填會怎樣?

輸出按位置從小到大重排:輸入順序 100、0、50 得到 linear-gradient(90deg, #8a2387 0%, #e94057 50%, #f27121 100%)。兩個色標同放 12% 就沒有插值區,硬邊出來——斜紋條正是靠 0%、12%、12%、24% 四個位置畫條紋,一個週期只佔 24%,後 76% 由平鋪重複 4.1667 次。

回到開頭那句「白字看不清」。我的依據是三步:把每個色標當純色算一遍,看最差值落在 4.5 還是 3 以下;確認報表裡有沒有中點,跨色相的就手動補一個,中段最容易失守;再核字級,24px 以上或 18.66px 粗體才允許停在 3。落日這組我最終把正文換成黑字(最差 4.59:1),白字只留給大號標題;霓虹那種白字 3.72、黑字 3.35 兩邊都不夠正文檔的,我不再拿它壓正文。問題不是漸層能不能用,是最差的那個色標沒人算過。

📎 相關文章

SOS 只有 9 個音,整句字母表要 104 個音:摩斯碼的節奏怎麼算出來 2026-10-21 轉盤上寫「權重 30」是幾成機會?扇區角度、放回與不放回的兩種抽法 2026-10-21 老照片放大就發糊?畫質提升能救回多少細節 2026-10-15 庫存標籤要條碼?CODE128 與 EAN-13 怎麼選 2026-10-15 拼豆圖紙怎麼做?把照片轉成色卡與網格 2026-10-15