十六进制颜色表

把 HEX 色值拆成 sRGB 三个通道,顺带算出这对白字黑字各是多少对比度、落在 WCAG 哪一档。

预览文字 The quick brown fox jumps over the lazy dog 0123456789
色CSS 命名HEXRGB相对亮度 L对白字对黑字推荐字色WCAG

使用方法

这个页面只有两个控件,核心动作是把一个 HEX 色值丢进去看它被拆成了什么。四步走:

  1. 在「HEX 色值」框里填色值。可以写 #315FE8(示例默认 6 位),也可以写 3af 这种 3 位缩写,甚至不带 #;填完直接按 Enter 或点「查表校验」。
  2. 想凭感觉挑色就用「可视选择」色块,拖动它,上面的 HEX 框会同步更新;反过来手打 HEX 时色块也会跟着跳。
  3. 结果区给出 5 个通道值和 2 个对比度。示例 #315FE8 拆出 rgb(49, 95, 232),对白字对比度 5.34(过 AA),对黑字 3.93(只过大字),所以推荐配白字。
  4. 想一次看一批色值就点「加载更多」,表格按 12 行一批往下加,加到 36 行封顶;要拿去核对就用「导出 CSV」或「复制对照表」。

能解决什么

做前端的时候,颜色最常出问题的不是选不出好看的,而是选完了不知道够不够清楚。十六进制颜色表解决的就是这件事的后半段。

典型场景一:设计稿给了 #7F7F7F 这种中灰,你直接放到按钮文字上,截图看着还行,但实际对比度只有 3.95:1,正文尺寸下达不到 WCAG AA。本页会把这个数字直接摆出来,并把推荐字色改成黑色。

典型场景二:品牌色要做深浅两套文字。#315FE8 这类中明度蓝,白字 5.34:1、黑字 3.93:1,二选一必须选白字——这就是本页第二个对照列存在的理由。

典型场景三:前端拿到设计给的 #ABC,想确认它和 #AABBCC 是不是同一个颜色。本页会把它展开成完整 6 位再拆通道,避免手算缩写出错。

本页不做的事:不在图片上取色(那是像素采样,见 图片颜色取色),不按色相生成一整套配色梯度(见 调色工具),也不做灰度模拟。红绿蓝和十六进制互转这种纯数值换算,本页结果里已经带了,不另开页面。

原理和变量

整张表建立在两个公式上:一个是 sRGB 的反伽马曲线,一个是 WCAG 的相对亮度加权。

第一步,把 6 位 HEX 拆成三个通道。用 parseInt(hex.slice(1), 16) 把字符串当成一个 24 位整数,然后右移 16 位取红、移 8 位取绿、低 8 位取蓝。#315FE8 拆开就是 49 / 95 / 232。3 位缩写 #3AF 按 CSS 规范每位重复两次展开成 #33AAFF,得到 51, 170, 255——注意展开后通道值会变,这正是缩写省下的那 4 个字符的代价。

第二步,算相对亮度 L。这里有个关键取舍:不能直接拿 0~255 的通道值加权,因为人眼对绿色的敏感度是红色的 3.36 倍,但对暗部并不敏感。所以先把每个通道做反伽马:c/255 <= 0.03928 ? c/12.92 : ((c/255+0.055)/1.055)^2.4,再按 L = 0.2126R + 0.7152G + 0.0722B 加权。0.03928 这个断点来自 sRGB 规范本身,不是随便取的整数;换成 0.04 或 0.039 都属于"约等于",在极暗色上会算出不一样的 L。

第三步,对比度。ratio = (L_亮 + 0.05) / (L_暗 + 0.05)。加 0.05 是为了给纯黑配纯白留出下限,否则 #000000 和 #FFFFFF 会算出除零。实测 #000000 对 #FFFFFF 正好是 21.00:1,这是这套公式能达到的上限。

第四步,定级。按 WCAG 2.1:正文对比度 ≥ 4.5 算 AA,≥ 7 算 AAA,≥ 3 只算大字号(18pt 或 14pt 粗体)。页面把「AA-Large」单独列成一档,就是因为它最容易被人误当成"通过"。

再解释一个容易搞混的点:为什么纯绿色比纯红色亮那么多。代入公式,#00FF00 的 L 是 0.7152,#FF0000 的 L 是 0.2126,正好是绿权重和红权重本身。这不是公式偏心,是人眼视网膜的构造如此——所以「绿色看起来刺眼但对比度低、红色看起来暗但对黑字友好」这类反直觉现象,公式能解释。

完整示例

下面这组数字全部由本页默认色 #315FE8 算出,控件默认值、这里的示例、下面表格的第一行数据三处一致(数值为演示用)。

  • 输入:#315FE8,6 位,带 #。
  • 通道:红 49、绿 95、蓝 232;HSL 约为 hsl(224.9, 79.9%, 55.1%)。
  • 相对亮度 L = 0.146636。
  • 对白字 #FFFFFF:5.34:1,超 4.5,判 AA,普通正文可用。
  • 对黑字 #000000:3.93:1,超 3 未到 4.5,判 AA-Large,只适合 18pt 以上大字。
  • 推荐字色:#FFFFFF。

拿同页表格里的两行做对照更直观:#767676 对白字 4.54:1(过 AA),而 #777777 只差一个色阶,对白字降到 4.48:1(掉到 AA-Large)。这类"差一位就掉档"的色值正是设计改稿时最容易翻车的地方,十六进制颜色表把它们并排列出来,就是为了让你在提交前先看见。

输入范围与对照表

输入侧的硬约束:长度 3 位或 6 位十六进制字符,允许带一个前导 #,不区分大小写,其余一律拒绝。

你写的本页怎么处理说明
#3AF展开为 #33AAFF3 位每位重复两次,通道值随之改变
3af展开为 #33AAFF允许省略 #
#aabbcc与 #ABC 等价缩写是 6 位的无损压缩,反向不可逆
#12345拒绝5 位不是合法形式,补 0 或写满 6 位
#GGGGGG拒绝G 不是十六进制字符
red拒绝本页只吃数值色值,色名查询在另一页

输出侧的等级对照,全部为实测值:

HEXRGB对白字等级对黑字等级该用哪边
#0000000, 0, 021.00AAA1.00Fail白字
#767676118, 118, 1184.54AA4.62AA都过,白字更稳
#777777119, 119, 1194.48AA-Large4.69AA黑字
#0000FF0, 0, 2558.59AAA2.44Fail白字
#949494148, 148, 1483.03AA-Large6.92AA黑字
#FFFF00255, 255, 01.07Fail19.56AAA黑字

页面下方 36 行速查表用同一套公式算,行列是 CSS 命名色、HEX、RGB、相对亮度、对白字对比度、对黑字对比度、推荐字色、WCAG 等级。36 行里每一行都至少有一种字色能过 AA——这不是巧合,纯粹黑到纯白的对比度上限有 21:1,任何 L 值总能落在某一边能过 4.5 的区间里。

边界与精度

色空间大小有硬上限。8 位 sRGB 每通道 256 级,三通道组合 2^24 = 16777216 种。3 位缩写只有 16^3 = 4096 种,是完整空间的 1/4096。也就是说缩写色在完整色域里是一份极稀疏的采样,用缩写写的设计稿没法再往里插 1 个单位的变化。

16bit 是另一回事。每通道 65535 级时总色数 2^48 ≈ 2.8×10^14,量化步长从 8bit 的 1/255(0.3922%)缩到 1/65535(0.0015%)。但写进 CSS 的是 8bit,浏览器会自行降级,所以 16bit 色值只在专业修图和打印链路里有意义,网页上写 16bit 没有精度收益。#315FE8 按 v/255×65535 放大到 16bit 是 12593, 24415, 59624,再降回 8bit 正好回到 49, 95, 232,这一来回无损,可以放心当往返测试用例。

对比度的上下界。公式在两端有天然极值:#000000 对 #FFFFFF 正好 21.00:1,一个数都加不上去;同色对比自身是 1.00:1。所以任何色值算出来的结果必然落在 1.00~21.00 之间,页面读到区间外的值就是有 bug,不是色值的问题。

浮点与四舍五入。亮度 L 是浮点数,全精度下保留 6 位小数展示(示例 0.146636);对比度展示保留 2 位小数。定级用未四舍五入的原值比较,因为 #767676 的 4.542 和 #777777 的 4.478 各自四舍五入到 4.5 和 4.5 看着一样,实际却分属 AA 和 AA-Large 两档——差这一位就是过与不过的区别。

8bit 通道和 16bit 通道的取整方向相反。8bit 放大到 16bit 是向上取整(精度增加),16bit 缩到 8bit 也是四舍五入(精度丢弃)。如果哪条链路是 16bit→8bit→16bit 反复来回,每次都会有不可逆的 ±1 抖动,别拿它当无损转换用。

清晰度不是数值问题。本页算的是数学对比度,不模拟任何具体屏幕、字体粗细或抗锯齿效果。同一对色值在高分屏和普通屏上肉眼观感不同,但那属于设备校准范畴,不在本页能解决的范围内。

常见问题

AA-Large 到底算不算通过?

看字号。WCAG 2.1 规定正文(小于 18pt,或小于 14pt 粗体)要 4.5:1,大字号只要 3:1。所以 AA-Large 意味着:这个配色用在大标题上没问题,用在 14px 正文上就是不合规。示例 #315FE8 对黑字 3.93 属于这一档,配 18px 以上大字合格,配正文不合格。

为什么 #777777 和 #767676 会差一档?

因为它们刚好骑在 4.5 这条线上:#767676 对白字 4.542 达标,#777777 是 4.478 差一点。色阶只差 1,肉眼看不出区别,但合规判定完全不同。所以十六进制颜色表展示 4 位小数而不是 2 位——展示时四舍五入到 4.5 会把两档混成一样,定级必须用原值。

3 位缩写和 6 位写法什么时候不等价?

永远等价,方向是单向的:#ABC 一定等于 #AABBCC,但 #123456 缩不成 3 位(缩写要求每一位的两位数字相同)。把 6 位缩到 3 位会丢 4 个字符、4096 倍精度;反过来 3 位展开成 6 位是无损的。

输入了色名比如 cornflowerblue 为什么报错?

本页的输入框只接受数值色值,这是刻意的边界:色名到 RGB 要查 CSS 命名色表,那属于另一类查询。如果要按名字反查色值,去 颜色名字查询;只想知道某个名字长什么样,直接看下面 36 行表的 CSS 命名列也可以。

相对亮度 L 可以大于 1 或者小于 0 吗?

不能。三个通道的反伽马值都在 0~1 之间,三个权重 0.2126 + 0.7152 + 0.0722 恰好加起来是 1.0000,所以 L 必然在 0~1。实测 #FFFFFF 的 L 正好是 1.000000,#000000 正好是 0.000000,两端都取到界。页面若显示超出这个范围,说明计算被污染了。

表里 36 行为什么没有全站所有颜色?

因为 CSS 命名色一共 148 个,全列出来对"速查"没有意义,页面会变成一堵墙。这里挑的是覆盖黑白灰阶、12 个基本色相、以及 12 个低饱和常用的浅色,共 36 行,按 12 行一批加载。想要 216 色 Web 安全立方色域那一套,去 WebSafeColors图表。

红绿蓝和十六进制的互转要另开一页吗?

不用。本页结果区第一行就是 rgb(49, 95, 232),已经完成了双向换算。如果你的场景是批量转换、要处理不带 # 的原始 RGB 串、或者要输出到代码里,专门的 十六进制转RGB 和 RGB转十六进制 会更顺手。

页面算出来的对比度能直接写进无障碍验收报告吗?

可以,但报告里要注明三件事:一是算法版本是 WCAG 2.1 的相对亮度法,不是 APCA;二是只覆盖了前景/背景两色,没算叠加透明度和背景图;三是没有模拟字体粗细与渲染。透明叠加后的实际对比度要单独算,色盲模拟可以配合 色盲模拟 一起看。

相关工具

  • 十六进制转RGB——单向换算,输出不带括号的三元组,适合直接贴进代码。
  • RGB转十六进制——反向换算,从 rgb(49, 95, 232) 这类串拿到 HEX。
  • 颜色名字查询——已知色值反查最接近的 CSS 命名色和十六进制。
  • WebSafeColors图表——216 色 Web 安全立方色域,覆盖老设备都能显示的子集。
  • 调色工具——按色相生成明暗梯度,本页只验证明暗两端的对比度。
  • 色盲模拟——把色值转成红绿色盲视角下看到的样子,验不出对比度但能看出色相混淆。
  • 颜色工具分类——同分类下还有 HSL / CMYK 互转、邻近色与三角色方案等 24 个工具。