颜色格式转换与对比度检查(HEX · rgb · hsl · WCAG 相对亮度)

把颜色在 HEX、rgb()、hsl() 之间互转并算出 WCAG 相对亮度,再检查前景色与背景色的对比度能否达到 WCAG 2.1 的 AA / AAA 门槛,不达标时给出最小的改法。全部在这台设备的浏览器里算。

① 单个颜色:写法互转加相对亮度。输入认 #f0a、#FF00AA、FF00AA、rgb(255, 0, 170)。

四组算好的颜色

打进去HEX(大写)rgb()相对亮度 L(WCAG)
#f0a#FF00AArgb(255, 0, 170)0.2416
rgb(119,119,119)#777777rgb(119, 119, 119)0.1845
#FFFFFF#FFFFFFrgb(255, 255, 255)1.0000
hsl(210, 60%, 40%)———

② 前景 / 背景对比度:逐条对照 WCAG 2.1 的五个门槛。上下两格各算各的,下面报错不会清掉上面的结果,反过来也一样。

换算的口径

一屏解决两件事

第一件是写法对不上。设计稿给 #FF00AA,CSS 里想要 rgb(),做主题变量时又用 hsl(),手工换算要么靠心算要么靠在线站点。这里三个写法加相对亮度一次列全,输入端宽松(# 可省、三位简写、rgb() 直接粘),读不懂时会指出是第几位、哪个字符不对,而不是笼统一句「格式错误」。

第二件是对比度到底够不够。#777777 放在白底上是经典的翻车案例:看着挺深,实测 4.48:1,差 0.02 就过不了正文 AA。这一栏把 WCAG 2.1 的五个门槛拆成表格逐条判,还会算出「最小改法」——只把一端挪几步就达标,而不是让你把整个配色推翻。

计算口径

解析:接受 RGB / RRGGBB(# 可选,忽略大小写与空格)和 rgb(r, g, b)(逗号或空格分隔,三项都得是 0–255 的整数)。拒绝颜色名称、四位/八位十六进制(含 alpha)、rgba()、带斜杠的新语法、百分比和小数,并给出具体的出错位置——先去掉所有空白,位置从 # 后面(rgb() 则是第几项)开始数起。

线性化:每个通道 c = v / 255,然后

c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ^ 2.4

相对亮度:L = 0.2126 × R + 0.7152 × G + 0.0722 × B(线性化之后的三个通道),显示 4 位小数。

对比度:ratio = (max(L1, L2) + 0.05) / (min(L1, L2) + 0.05),显示 2 位小数,判定用未取整的值。

门槛来自 WCAG 2.1:正文 AA ≥ 4.5、正文 AAA ≥ 7;大字 AA ≥ 3、大字 AAA ≥ 4.5,其中「大字」定义为 ≥ 18.66px 且字重 ≥ 700,或 ≥ 24px;非文本 UI 组件与图形(1.4.11)≥ 3。

HSL:标准 RGB→HSL 换算,色相四舍五入到整数度,S 与 L 保留 1 位小数;纯灰(最大最小相同)按约定记 hsl(0, 0.0%, l%)。

不达标时的建议:把前景或背景之一按通道等比推向纯黑或纯白(v ← v + (target − v) × i/255,等比移动所以色相和饱和度基本不变),四个方向各逐步试到 4.5:1 为止,报告所需步数最少的那个,并给出改完的 HEX 与新比值。

什么时候这些数字会骗你

  • 它假设你的屏幕是 sRGB。未校色的显示器、广色域手机、开着的「护眼模式 / 原彩 / Night Shift」、被浏览器接管的色彩管理,都会让你实际看到的颜色和 119/255 这个数不是一回事。同一串十六进制在不同机器上的对比度可以差出 0.2–0.5,这不是 bug,是配置文件的锅。
  • 对比度是亮度数学,不是「好不好看」也不是「看不看得清」。字重、字体、行距、抗锯齿、文字压在图片上、纯色块的观感轻重都不在公式里。AA 是法定最低门槛,不是舒适线;能上 AAA 就上 AAA。
  • 红绿色觉差异不在公式内。相对亮度对红色通道权重最低,#FF0000 在白底上只有 4.00:1,而同一亮度的绿色能轻松过 7:1——靠颜色区分状态的时候,请另外加图标或文字。
  • 半透明不参与。带 alpha 的写法这里直接拒收,正确做法是先把它和真实背景合成一个不透明色,再拿合成结果来测。
  • 阈值边界会抖动。4.497 显示成 4.50 却判不通过;反过来 4.504 判通过。真在乎就用 4.6 / 7.1 这类留了余量的目标值。

常见问题

Q:为什么 #FFFA、rgba() 收得这么严? 因为 alpha 一旦参与,「对比度」就不成立了:同一个 rgba(0,0,0,.5) 叠在白底和黑底上是两个完全不同的颜色。这里宁可让你先去合成、再来测,也不给一个看着像结论其实随背景漂移的数字。

Q:过 AA 就行,还是必须 AAA? AA 是合规底线(多数法条与内部规范引用的就是它)。AAA 适合长文正文、年龄层偏高或低照度的场景。表格把两档都列出来,就是为了让你自己决定,而不是替你决定。

Q:我填的颜色去了哪里? 解析、线性化、比值全部写在脚本里,没有哪个环节会把你的颜色发出去,你输入的颜色不会离开这台设备。

微信
微信
支付宝
支付宝