">颜色工具

互补色查询

输入一个 hex 色值,按 HSL 色相环补角 H+180° 给出互补色;同时给出 CIELAB 转 LCH 后按色相差 180° 求出的感知补色,并标出哪些因为超出 sRGB 色域被裁剪。

#315FE8原色 · HSL(225, 80%, 55%)
#E8BA31HSL 补角 H=45°

三条固定规则(与输入色无关)

  • HSB 补色是另一套规则(S→1−S、V→1−V),本页不提供该输出:实测红色的 HSB 补色是黑色,与 HSL 的 #00FFFF 完全不同。
  • 无色相的色补色等于自身:S=0%(灰阶)、L=0%(纯黑)、L=100%(纯白)三种情况下 HSL 公式的分母 M−m 为 0,色相不参与计算。这不是计算失败,是「无色可补」。
  • 色相环首尾相接,360° 等价 0°,所以补角一律对 360 取模。

使用方法

  1. 用取色器点一下,或直接在文本框里填 hex 色值。#RRGGBB(六位)与 #RGB(三位缩写)都收,字母大小写随意:#315fe8、#315FE8、#abc 都能识别。页面打开时预置的是本站主色 #315FE8。
  2. 点「查互补色」,或在色值框里按 Enter。左边色块是原色,右边是HSL 补角(保持 S 与 L 不变、色相旋转 180°),两块的色值同时以大字号显示。
  3. 看结果区下方的提示。它会给出 CIELAB 空间下的感知补色——那是一个完全不同的颜色:HSL 补角会改变明度,感知补色保持明度不变。如果提示里写了「已裁剪」,说明请求的色度超出了 sRGB 能表达的范围。
  4. 点「复制两个色值」把原色与补色的 hex 一次带走(TSV 两行,可直接粘进 CSS 变量表);点「载入示例」回到 #315FE8;点「清空」清掉色值框(此时会提示允许的格式,不会静默按黑色计算)。

这个互补色查询能解决什么问题

一是给已有品牌色找配对色。你手上有一个主色,需要一个在色相环上正对面的颜色做按钮底色、图表第二序列、或者深色模式下的强调色。直接取补角能得到数学上「最不同」的那个颜色。

二是避免「红配绿」这个经典错误。在美术的颜料色彩学(RYB 色轮)里红色的补色是绿色,但在屏幕的 RGB 加色混色里,红色(色相 0°)的补色是青色 #00FFFF(色相 180°)。这是本页最值得记住的一条:色轮有两种,别混用。本页所有计算都在 sRGB / HSL 空间进行。

三是判断某个配色是否真的「对比强」。HSL 补角保证色相差 180°,但不保证感知上的差异大——两色的明度可能接近(深蓝配深蓝),也可能差得离谱(正红配亮青,刺眼)。CIELAB 的 L* 与 C* 数据能告诉你实际差多少,页面上把两组结果的差值 ΔE76 直接算出来给你看。

四是为色盲用户检查配对色。约 8% 的男性有红绿色觉障碍,红绿配对对他们来说几乎一样。互补色(色相差 180°)在色觉障碍模拟下通常仍可区分,因为色相差远大于红绿轴的混淆范围——这一点比红绿配对安全得多。想自己验证,用「色盲模拟」把本页输出的两个色值丢进去看一眼。

本页不做这些事:不做三色配色方案(那是三角色色相分配,差 120° 不是 180°);不做邻近色(差 30°);不做渐变配色;不保证输出色通过 WCAG 对比度要求(补色只管色相,不管明暗)。要整套方案请用「邻近色颜色方案生成器」或「三角色颜色方案生成器」;要调明暗梯度请用「浅色颜色生成器」与「深色颜色生成器」;想知道某个色值的通用名称请用「颜色名字查询」。

原理:三种颜色空间下的「互补」不是同一个东西

第一种是 HSL 补角,公式是 H' = (H + 180) mod 360,S 与 L 保持不变。HSL 是 CSS Color 3 定义的颜色空间,转换分两步。RGB 转 HSL:先取 M = max(r,g,b)、m = min(r,g,b),L = (M+m)/2;S 分两段算——L < 0.5 时 S = (M−m)/(M+m),L ≥ 0.5 时 S = (M−m)/(2−M−m);H 看哪个通道最大:M=r 时 H = 60 × ((g−b)/(M−m) mod 6),M=g 时加 2,M=b 时加 4,最后把负值加 360。HSL 转 RGB:C = (1 − |2L−1|) × S,H' = H/60,X = C × (1 − |H' mod 2 − 1|),m = L − C/2,然后按 H' 落在 0~1 / 1~2 / 2~3 / 3~4 四个区间取 (C,X,0) / (X,C,0) / (0,C,X) / (0,X,C),最后每项加 m。关键取舍:取补角时只动 H,不动 S 与 L。这样做的理由是 HSL 的 H 维度是色相环上的角度,旋转它不改变「这个颜色有多鲜艳」和「有多亮」这两项感知属性;但代价是补色的明度可能与原色差很远(见下)。

第二种是 HSB / HSV 补色,算法与 HSL 完全不同。HSV 需要把 S 和 V 一起取反:H' = H + 180、S' = 1 − S、V' = 1 − V。实测差别极大:红色的 HSV 是 (0°, 100%, 100%),按这个规则补出的是 S'=0, V'=0 即黑色;而 HSL 补角给出的是 #00FFFF 青色。十二组实测里,HSL 补角与 HSV 补色没有一组相同。所以从 Photoshop 抄来的 HSB 数值不能直接套到 CSS 上——这是很多人算错的原因。

第三种是 CIELAB / LCH 感知补角,这是最「科学」但也最受限的一种。转换链路是四步:① sRGB 线性化,c ≤ 0.04045 时 c/12.92、否则 ((c+0.055)/1.055)^2.4;② 线性 RGB 乘 D65 矩阵得 XYZ,Y = 0.2126729R + 0.7151522G + 0.0721750B,白点 (0.95047, 1, 1.08883);③ 算 L* = 116f(Y/Yn) − 16、a* = 500(f(X/Xn) − f(Y/Yn))、b* = 200(f(Y/Yn) − f(Z/Zn)),其中 f(t) = t^(1/3)(t > 0.008856)否则 7.787t + 16/116;④ 转 LCH:C* = √(a*² + b*²)、h = atan2(b*, a*) 归一到 0~360°。CIELAB 的设计目标就是让数值距离接近视觉差异,所以在这里取补色的正确做法是只转色相 180°、保持 L* 与 C* 不变。红 #FF0000 的实测值是 L*=53.24、C*=104.55、h=40.00°;保持 L*=53.24 与 h=220.00° 时,sRGB 能表达的最大 C* 只有 31.06,远小于原来的 104.55——这就是「色域裁剪」,结果是 #008CA1。

为什么 CIELAB 补色要裁剪,为什么这件事很重要。sRGB 只是一个设备无关的显示约定,能表达的颜色是有限的三维立方体(1677 万色)。任何在 LCH 里合法但落在立方体外的颜色,转换回 sRGB 时三个通道里至少一个会超出 [0,1],只能被截断到边界。本页的做法是二分搜索最大可行色度(固定 L* 与 h,让 C* 从 0 逐步增大直到刚好越界),而不是简单地把超出的通道 clip 掉——后者会明显改变色相,产生偏色。实测差异:红色 HSL 补角是 #00FFFF(L*=91.11,被抬亮了 37.87),LCH 补色是 #008CA1(L*=53.31,基本保持原明度),两者 ΔE76 = 45.3——这是两个视觉上明显不同的颜色,选哪个取决于你要「色相对立」还是「感知对立」。

完整示例(数值均为实测)

页面默认色值是本站主色 #315FE8。实测结果:

这个例子把三种做法的差别显示得很清楚:#E8BA31 是个明亮的橙黄色,#5C7400 是个深橄榄绿。HSL 补角保留了饱和度但把明度从 55% 拉到了 50% 附近、且色相落在暖色区;LCH 补角把明度钉在 L*=45.2 几乎不动,但因为要保住 C*=80.8 的高饱和度,色相只能落在绿到黄之间。如果你在深色界面上做强调色,#E8BA31 在深底上对比度更好;如果你要的是「同样深、同样艳、方向相反」,#5C7400 才是对的。

再看红色这个最经典的例子。红色 #FF0000 的 HSL 补角是 #00FFFF 青色,而 CIELAB 感知补色是 #008CA1 蓝绿色——两者差 ΔE76 = 45.3。中文命名上要注意:红色的互补色是青不是绿(H=0° → H=180° = cyan);绿色的补色是品红(H=120° → 300° = magenta);蓝色的补色是黄(H=240° → 60° = yellow)。CSS Color 4 里这三个名字分别对应 #00FFFF、#FF00FF、#FFFF00。

十二组实测对照表与输入范围

下表是十二个色值在两种算法下的输出。「已裁剪」列标记的是那种「保持 L* 与 C*、只转色相」的请求落在 sRGB 色域外、必须二分收敛到边界的颜色;ΔE76 是两组补色之间的 CIELAB 欧氏距离,数值越大说明两种算法分歧越厉害:

原色HSLHSL 补角LCH 感知补色已裁剪ΔE76
#FF00000°100%50%#00FFFF#008CA1是45.3
#00FF00120°100%50%#FF00FF#F1D1FF是93.8
#0000FF240°100%50%#FFFF00#2C5600是85.6
#FFFF0060°100%50%#0000FF#F5F6FF是144.8
#FF00FF300°100%50%#00FF00#00A850是62.8
#00FFFF180°100%50%#FF0000#FFDEDF是100.8
#315FE8224.9°79.9%55.1%#E8BA31#5C7400是46.5
#8B451325.0°75.9%31.0%#13598B#00607A是17.4
#1E90FF209.6°100%55.9%#FF8D1E#9B9200是48.4
#FFC0CB349.5°100%87.6%#C0FFF4#95DED6否12.5
#2F4F4F180.0°25.4%24.7%#4F2F2F#5D4344否8.9
#7F7F7F0°0%49.8%#7F7F7F#7F7F7F否0.0

从这张表能读出三条规律:① 纯色与高饱和色的分歧最大——黄色的 ΔE76 = 144.8 是全表最高,因为黄色的 L* = 97.1 已经接近白,转 180° 之后请求的高饱和浅色几乎无法在 sRGB 里实现,只能大幅削色度;② 低饱和色的分歧最小——粉色 #FFC0CB 只有 12.5,深灰 #2F4F4F 只有 8.9;③ 灰阶完全没有色相——#7F7F7F 的 S = 0%,此时 HSL 里 H 不参与计算(公式中 M−m = 0),补色就是它自己,ΔE76 = 0。这不是 bug,是「无色可补」的必然结果。

三位缩写写法会先展开成六位再算,实测三组:#abc → #AABBCC(H=210°、S=25%、L=73.3%)→ 补角 #CCBBAA;#369 → #336699(H=210°、S=50%、L=40%)→ 补角 #996633;#963 → #996633(H=30°、S=50%、L=40%)→ 补角 #336699。最后一组正好互为补角,可用来验证展开逻辑没写反。

边界、精度与常见误读

常见问题

为什么红色的互补色是青色不是绿色?

因为有两种色轮。在美术的颜料色彩学(RYB 色轮)里红色对绿色,那是颜料的减色混色,油画里红和绿放一起确实互相削弱。但在屏幕的 RGB 加色混色里不一样:色相 0° 是红,转 180° 到 180° 就是 cyan,实测 #FF0000 的 HSL 补角是 #00FFFF。网页、UI、图表全是加色,所以本页一律按 RGB 算。你在设计工具里看到「红配绿」的说法,那是在说印刷品。

HSL 补角和 CIELAB 感知补色,我该用哪个?

看你需要哪种「对立」。要色相环上的正对面(比如图表里两组数据要明显区分、logo 需要对比强烈的配色),用 HSL 补角,它保证色相差正好 180°。要感知上的等强度对立(比如深色界面上找一个不刺眼又不沉闷的强调色),用 CIELAB 感知补色,它保持明度与彩度不变。两者在纯色上差得很远——黄色的 ΔE76 高达 144.8,视觉上完全不是一回事。本页两个都给出来,你自己挑。

「已裁剪」是什么意思?我的颜色被改了吗?

没改错,但你要求的那组 LCH 参数在 sRGB 里不存在。sRGB 只能表达 1677 万种颜色,构成立方体;当你要求「保持 L*=53.24、C*=104.55、色相转到 220°」时,落点在立方体外面。本页的做法是固定明度与色相,二分搜索出刚好在边界内的最大彩度(红色的结果是 C*=31.06,比原值低得多),所以叫「裁剪」。标记为「已裁剪」表示彩度被降低了;标记「否」表示原色度完整保留。

灰色的互补色就是它自己,这是出错了吗?

不是出错。HSL 公式里 S = (M−m)/(M+m),灰色三个通道相等所以 M−m = 0,S = 0%;而 H 的计算全部除以 M−m,分母为 0 时 H 无意义。灰阶在色相环上没有位置,所以「转 180°」这个操作对它没有意义,补色自然等于原色。实测 #000000、#808080、#FFFFFF 三者都是如此,CIELAB 侧 C* = 0.00 也是零。页面上会明确告诉你「无色相」,不会假装算出了什么。

为什么 Photoshop 里同一个颜色算出的补色和这里不一样?

最可能是三点之一。一,PS 用的是 HSB 或 HSL 面板,而补色规则不同:HSB 要 S→1−S、V→1−V,HSL 只转 H。实测红色的 HSB 补色是黑色(S=0,V=0),HSL 补色是青色,差得极远。二,PS 的「色轮」可能是 RYB 模式(绘画默认),转 180° 得到的是颜料补色而不是 RGB 补色。三,PS 的滑块是 0~255 取整,累积误差与这里的 8 位量化同级。如果你需要两边一致,先确认工具用的是 RGB/HSL 模式并统一到 sRGB 配置文件。

三位缩写和六位写法算出来一样吗?

一样,因为三位会先展开成六位:#abc 展开为 #AABBCC(每位数字重复两次)。实测 #abc(H=210°、S=25%、L=73.3%)的补角是 #CCBBAA,#AABBCC 的补角也是 #CCBBAA。所以用哪种写法不改变结果,只是六位能表达 1677 万色、三位只有 4096 色。注意展开规则是按位重复,#369 展开是 #336699 而不是 #336699 之外的任何值——实测 #369 与 #963 互为补角,可用来验证没写反。

互补色能用在我网站的文字上吗?

不建议直接用。补色只解决色相对立,不管明暗对比。红 #FF0000 配青 #00FFFF 互为补色,但在白底上红色的对比度约 3.9:1、青色约 1.25:1,都达不到 WCAG AA 对正文要求的 4.5:1(大字号要 3:1)。把补色当色块与强调元素用没问题,做正文文字必须用「颜色对比度检测」或「调色工具」另行验证并调整明度。

我输入的色值会被上传或保存吗?

不会。颜色转换由页面内的 JavaScript 完成,只用到几条乘法和一次二分搜索,没有任何 fetch 或 XMLHttpRequest 调用,也不写 localStorage;刷新后色值框回到 #315FE8。想自己确认,打开开发者工具的 Network 面板,改动色值时观察是否有请求发出——不会有。

相关工具