雜記 › 資源分享 › HEX、RGB、HSL 顏色怎麼互轉?線上取色與對照一次講清

HEX、RGB、HSL 顏色怎麼互轉?線上取色與對照一次講清

替公司的元件庫補深色模式時,我接手過一份只寫 HEX 的色值規範。設計同事要求「hover 態就是主色深一點點」,聽起來是半句話的事,我卻在那個藍色上反覆對不齊:手工把 #1E90FF 換算成 HSL 時飽和度算成了 88%,改完亮度再轉回 HEX,已經變成另一個顏色。同一顆按鈕在設計稿和網頁上差了一檔,評審時被當成「還原度問題」來回扯了兩天。顏色格式本身不難,難的是三套寫法之間來回換算時人手最容易出錯的那幾步。

一、三種寫法描述的是同一個東西,只是座標軸不同

HEX 和 RGB 是同一套「紅綠藍三通道」的兩種記法,HSL 換了一組更貼近直覺的軸:色相、飽和度、亮度。同一種藍的四種寫法放在一起是這樣:

格式寫法這一種藍的取值分量範圍什麼時候用它
HEX#RRGGBB#1E90FF每兩位 00–FF設計稿標註、CSS 變數、品牌色文件
RGBrgb(r,g,b)rgb(30,144,255)各通道 0–255需要參與計算、和 JS 打交道
HSLhsl(h,s%,l%)hsl(210,100%,56%)H 0–360,S/L 0–100%衍生深淺、做主題色階
RGBArgba(r,g,b,a)rgba(30,144,255,0.5)A 為 0–1遮罩層、懸浮態半透明

主題色體系裡 HSL 更省事的原因就在這:只動 L,H 和 S 保持不變,得到的就是同色相的深淺一檔。上面那個藍把亮度從 56% 壓到 46%,得到約 rgb(0,117,235),也就是接近 #0075EB 的深色,正好用作 hover。

二、手算為什麼會錯:兩個公式的必經中間量

HEX 轉 RGB 是無腦的,兩位十六進位查表即可:1E=30、90=144、FF=255。問題出在 RGB 到 HSL,必須先拿到最大值和最小值:

  • 亮度 L = (max + min) / 2。那個藍裡 max=255、min=30,(255+30)/2/255 ≈ 56%。
  • 飽和度 S = (max − min) / (1 − |2L − 1|),分母裡的 |2L−1| 是所有人漏掉的那一項。我當初直接用了 (max−min)/max,算出 88%,而正確值是 100%。
  • 色相要按「哪個通道最大」分三段選公式,算出來還可能是負數,得加 360 再取模。這一步手算幾乎必錯。

反方向從 HSL 回 HEX 還要再經過 chroma 和中間量,兩套公式互推一次就是十幾次乘除。顏色這件事上,手算的性價比極低——我現在都是在顏色轉換裡輸入任一種格式,讓三種值同時出來,再複製需要的那種。

三、帶透明度時最坑的一點:8 位 HEX 的位元組順序

CSS 裡的 8 位十六進位是 #RRGGBBAA,透明度在最後:rgba(30,144,255,0.5) 寫成 HEX 是 #1E90FF80(0.5 × 255 ≈ 128 = 80)。但 Android 的顏色整數、不少設計外掛和圖片格式用的是 #AARRGGBB,透明度在最前。同一個數值挪了位置,讀出來就是完全另一個顏色:把 #1E90FF80 當成 #AARRGGBB 解析,透明度取的是 0x1E,只有約 12%,剩下的三個位元組被讀成 rgb(144,255,128)——本來該是半透明藍的遮罩層,結果變成一層幾乎看不見的淺綠。我那次半透明遮罩層在 iOS 端一片怪色,就是栽在這個順序上。跨端傳色值時,寧可多寫一行註解標明通道順序。

四、色值定了之後,還要看它和背景能不能讀清

WCAG 對正文與背景要求的對比度是 4.5:1,大字級文字放寬到 3:1。拿 #1E90FF 配純白算,相對亮度約 0.27,對比度約 3.2:1——在白底上放小字其實不合格;換成壓暗一檔的 #0075EB,對比度升到約 4.4:1,仍差一點點,得再把 L 往下調幾檔。這類判斷不需要儀器,需要的是別把「好看」當成「看得清」。

還有兩個會偷偷改變色值的環節:一是取色來源,螢幕截圖取色時如果圖片帶 ICC 設定或做過壓縮,讀到的 RGB 會和設計稿差 1–3 個單位;二是螢幕,普通辦公螢幕覆蓋 sRGB 不足時,飽和度高的綠和藍會明顯偏灰。規範落地時我更傾向固定 HEX,HSL 只作為衍生工具使用。

五、常見疑問

Q:#fff 這種三位寫法是什麼?

是 #ffffff 的縮寫,規則是每一位都恰好重複兩次才行。#1E90FF 不能縮寫,#FF00AA 可以寫成 #F0A。

Q:HSL 裡的 H 為什麼到 360 又回到紅色?

因為色相是一個圓:0 紅、60 黃、120 綠、180 青、240 藍、300 洋紅,360 與 0 重合。做同色系衍生時讓 H 加減十幾度就是鄰近色,加 180 度是互補色。

Q:L 調到 0 和 100 會發生什麼?

L=0 是純黑、L=100 是純白,此時 S 和 H 都不再影響結果。所以「給一個色加亮」調到 90% 以上就會開始失去色相,深色模式裡的字色通常停在 70%–90% 之間。

Q:主題變數到底存 HEX 還是 HSL?

看你要改哪個維度。只換深淺、做亮暗兩套主題,存 HSL 更好算;只做整體替換品牌色、且要和設計稿一一對齊,存 HEX 更直觀。兩者可以無損互轉,不必擔心後期改不回來。

Q:從介面截圖裡取的色為什麼和規範對不上?

截圖鏈路會做色彩管理和壓縮,取到的值可能有 1–3 的偏差。要精確值時優先從設計檔案裡的標註或 CSS 變數本身取,再順手換算成需要的格式。

現在那個元件庫的規範是兩層:HEX 作為唯一權威值,HSL 只用來生成狀態色並在文件裡附一行換算結果。當初那兩天的來回,本質上是把「深一點」這種模糊描述直接交給了兩種座標系——把換算變成一次輸入輸出的固定動作之後,這類分歧就不再需要開會解決了。

📎 相關文章

SOS 只有 9 個音,整句字母表要 104 個音:摩斯碼的節奏怎麼算出來 2026-10-21 轉盤上寫「權重 30」是幾成機會?扇區角度、放回與不放回的兩種抽法 2026-10-21 漸層底上的白字為什麼總看不清?把 WCAG 對比度逐個色標算一遍 2026-10-21 老照片放大就發糊?畫質提升能救回多少細節 2026-10-15 庫存標籤要條碼?CODE128 與 EAN-13 怎麼選 2026-10-15