使用方法
页面打开就带一组示例:前景色 #3498DB、背景色 #FFFFFF、alpha 0.6,三张卡片立刻给出背景色原样、sRGB 合成色、线性光合成色。改任意一个输入框,三张卡片与状态行同时刷新,不必点按钮;在输入框里按回车同样触发计算。
- 填前景色 HEX:写 6 位十六进制,必须带
#,字母大小写都收,#3498db与#3498DB等价。也可以直接点右侧色块选色,选完文本框会自动跟上。 - 填背景色 HEX:同样 6 位、带
#。背景色是不透明的那一层,alpha 只作用于前景色,所以写成 3 位简写、8 位带 alpha、或漏掉#都会被判不合法,并在错误区说明原因。 - 填不透明度 alpha:范围 0 到 1,步长 0.01。0 表示前景完全透明、结果等于背景色;1 表示前景完全实心、结果等于前景色。填 1.5 会被拦下,错误区会写出「不能大于 1」以及当前写的那串字符。
- 读三张卡片:第一张是背景色原样,用来确认背景没写错;第二张是 sRGB 数值空间按 alpha 直接插值的结果,也是多数浏览器处理 rgba 背景的方式;第三张是先把两色转成线性光、混合、再编回 sRGB 的结果,整体更亮。每张卡都给 8 位 hex 与 rgb 三元组。
- 复制或导出:alpha 量化表上方有「复制 TSV」和「导出 CSV」两个按钮。表格默认显示 12 行,点「加载更多」展开到全部 20 行;CSV 带 UTF-8 BOM,Excel 双击打开不乱码。
三个输入全部合法才会计算。任何一项不合法时,结果区变成红色错误条,写清楚是哪一项、错在哪、当前写的是什么,不会静默输出一个数。
能解决什么
半透明叠加看起来只是「乘个 alpha 再加一加」,实际有两种口径,选错就会出现「设计稿上是这个色,落到页面上偏暗」的扯皮。Transparent颜色计算器把两种口径并列摆出来,让人一眼看见差多少、该用哪一种。
- 设计标注 rgba(52, 152, 219, 0.6) 要落到白底卡片上,先算出确切色值再写进样式,不用在取色器上凭眼睛猜。
- 深色主题里把半透明前景压到深色背景上,判断该用 sRGB 还是线性光,防止文字发灰、对比度掉档。
- 做加载遮罩、骨架屏、图片水印时,先算合成结果,再决定 alpha 取 0.5 还是 0.6 才能达到想要的灰度。
- 把带 alpha 的 8 位 hex 写进配置文件前,先看 alpha 被量化成哪一档、回程误差多大,避免 0.3 写进去读回来变成 0.302。
- 核对设计工具与代码实现的差异:Figma 的混合、Canvas 的 globalAlpha、CSS 的 rgba 走的空间并不总是一致,这里给出可对照的数字。
它不判断「哪个更好看」,只把两种空间下的确切数值、量化误差和取整边界摆清楚;选哪种由业务决定,页面负责把账算对。
原理和变量
设前景色 sRGB 三元组为 Cs、背景色 sRGB 三元组为 Cb、不透明度为 alpha,三者是页面仅有的输入。Cs 与 Cb 各取 0 到 255 的整数,alpha 取 0 到 1 的实数,输出记作 Co。
sRGB 数值空间直接用 alpha 做线性插值,也就是 source-over 在 sRGB 坐标下的直通形式:Co = alpha × Cs + (1 − alpha) × Cb,逐通道独立计算,最后四舍五入到整数。它快、可预期,也是浏览器对 rgba 背景最常用的处理方式。
线性光空间先把两色从 sRGB 编码值解码成线性光强,在线性光里按同样的 alpha 插值,再编码回 sRGB,最后乘 255 取整。解码与编码是同一对函数的逆:
dec(c) = c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ^ 2.4
enc(v) = v <= 0.0031308 ? 12.92 × v : 1.055 × v ^ (1 / 2.4) − 0.055
两套公式唯一的差别是「在哪个空间里插值」。sRGB 编码值不是线性光强,0.5 的编码值对应的实际亮度只有约 0.214,所以在编码值上直接插值,得到的中间色比线性光插值更暗;alpha 越接近 1 差距越小,alpha 等于 1 时两套结果完全相同。
8 位 hex 的 alpha 只有 255 档。页面先把 alpha 乘 255 再四舍五入得到字节值,回程用「字节值 ÷ 255」,两者之差就是量化误差,最大约 0.00196。这个误差会原样写进 8 位 hex,被任何读取方继承。
完整示例
以默认输入为例:前景色 #3498DB,即 Cs = (52, 152, 219);背景色 #FFFFFF,即 Cb = (255, 255, 255);alpha 取 0.6。
sRGB 数值空间逐通道代入 Co = 0.6 × Cs + 0.4 × Cb:R 通道 0.6 × 52 + 0.4 × 255 = 31.2 + 102 = 133.2,G 通道 91.2 + 102 = 193.2,B 通道 131.4 + 102 = 233.4。三路四舍五入得 133、193、233,即 #85C1E9。
线性光空间先解码:dec(52/255) ≈ 0.03434、dec(152/255) ≈ 0.31399、dec(219/255) ≈ 0.70838,而 dec(255/255) = 1。按 alpha 混合得 0.42060、0.58839、0.82503,再编码得 0.68042、0.79083、0.91875,乘 255 得 173.51、201.66、234.28,四舍五入为 174、202、234,即 #AECAEA。
两个结果在 R、G、B 上的差分别是 41、9、1,最大差 41。这就是同一组输入在两种空间下的全部差异:sRGB 偏暗,线性光偏亮,且暗部差距最大。
对照表
下表把 alpha 从 0.05 到 1.00 按 0.05 步长逐档列出:alpha 先乘 255 得到精确乘积,四舍五入后才是能写进 8 位 hex 的字节值,回程 alpha 用字节值除以 255,两者之差就是量化误差。误差只有 0、+0.00098、−0.00098、+0.00196、−0.00196 五档,没有更大的可能。
| alpha | alpha × 255 | 8 位 hex | 十进制 | 回程 alpha | 误差(回程 − alpha) |
|---|---|---|---|---|---|
| 0.05 | 12.75 | 0D | 13 | 0.05098 | +0.00098 |
| 0.1 | 25.5 | 1A | 26 | 0.10196 | +0.00196 |
| 0.15 | 38.25 | 26 | 38 | 0.14902 | −0.00098 |
| 0.2 | 51 | 33 | 51 | 0.2 | 0 |
| 0.25 | 63.75 | 40 | 64 | 0.25098 | +0.00098 |
| 0.3 | 76.5 | 4D | 77 | 0.30196 | +0.00196 |
| 0.35 | 89.25 | 59 | 89 | 0.34902 | −0.00098 |
| 0.4 | 102 | 66 | 102 | 0.4 | 0 |
| 0.45 | 114.75 | 73 | 115 | 0.45098 | +0.00098 |
| 0.5 | 127.5 | 80 | 128 | 0.50196 | +0.00196 |
| 0.55 | 140.25 | 8C | 140 | 0.54902 | −0.00098 |
| 0.6 | 153 | 99 | 153 | 0.6 | 0 |
| 0.65 | 165.75 | A6 | 166 | 0.65098 | +0.00098 |
| 0.7 | 178.5 | B3 | 179 | 0.70196 | +0.00196 |
| 0.75 | 191.25 | BF | 191 | 0.74902 | −0.00098 |
| 0.8 | 204 | CC | 204 | 0.8 | 0 |
| 0.85 | 216.75 | D9 | 217 | 0.85098 | +0.00098 |
| 0.9 | 229.5 | E6 | 230 | 0.90196 | +0.00196 |
| 0.95 | 242.25 | F2 | 242 | 0.94902 | −0.00098 |
| 1 | 255 | FF | 255 | 1 | 0 |
复制与导出始终覆盖全部 20 行,不受当前显示行数影响;导出的 CSV 第一列为 alpha 原值,第二列为精确乘积,第三列才是真正写进文件的字节。
结果边界与舍入
所有取整都用四舍五入,且只做一次,不在中间步骤反复取整。中间值一律保留完整双精度,直到最后一刻才 round。
- alpha = 0:两套结果都等于背景色,误差为 0,此时选哪种空间没有区别。
- alpha = 1:两套结果都等于前景色,与背景色完全无关,此时背景写错也看不出来。
- 前景等于背景:任意 alpha 下结果都等于该颜色,两套空间一致,可用来验证输入有没有写错。
- x.5 的中间值:如 0.6 × 52 + 0.4 × 255 = 133.2 不涉及,但 0.5 × 255 = 127.5 一律进位到 128,所以黑 50% 压白得到 #808080 而不是 #7F7F7F。
- 线性光阈值:解码用 0.04045、编码用 0.0031308 两个门槛,门槛以下走线性段 12.92 倍,门槛以上走幂函数段;12.92 × 0.04045 = 0.522614,两段在门槛处连续。
- 8 位精度封顶:输出只有 256 级,任何小于 1/255 的差异都会被吃掉;线性光算出的 173.51 与 sRGB 算出的 133.2 不可能靠调 alpha 精确对齐。
- 两种空间的最大差:黑压白时,alpha 在 0.8 附近差得最多,达 73;alpha 到 0.5 时差 60,alpha 到 0.1 时只差 13。
- 越界即报错:alpha 小于 0 或大于 1、HEX 长度或字符不对,都会停下并给出具体文案,不会截断到合法区间后继续算。
常见问题
半透明叠加到底该用哪种算法?
看目标平台。CSS 的 rgba 背景在多数浏览器里走 sRGB 数值空间;涉及物理光、图像合成、HDR 或需要保留暗部层次的场景走线性光空间更稳。页面把两种结果都给出来,你可以按落地环境挑。
为什么线性光结果比 sRGB 亮?
sRGB 编码值经过了伽马压缩,中间值对应的实际亮度比数值本身低。在编码值上插值等于在压缩后的空间里取平均,结果偏暗;先解码到线性光再插值,才是对光强本身取平均,再编码回来就更亮。差距在暗部最大,亮部趋近于零。
黑 50% 压白为什么是 #808080?
0.5 × 0 + 0.5 × 255 = 127.5,四舍五入进位到 128,128 写成十六进制正是 80。若用「逢五舍」会得到 127 即 #7F7F7F,与本页口径不同,差值只有 1,但在渐变端点能看出一条细缝。
8 位 hex 的 alpha 够用吗?
255 档在静态色块上肉眼几乎分辨不出,但在大面积渐变、多层叠加或做精确 brand 配色时会累积偏差。若要求 alpha 精确到小数点后三位以上,应改用浮点表示或在样式里直接写小数,不要走 8 位 hex。
CSS 里的 rgba() 和这里一致吗?
多数情况下一致,因为浏览器对 rgba 背景同样按 sRGB 数值空间逐通道插值。但涉及滤镜、混合模式 mix-blend-mode、Canvas 合成或颜色空间声明 color(display-p3 …) 时,实际走的空间可能不同,落地前最好按目标环境单独验一次。
背景色本身带透明度怎么办?
本页只做两层合成,背景被默认为不透明。若背景也带 alpha,正确做法是先算背景与它下面那一层的合成结果,再把得到的不透明色当作本页的背景色代入,逐层从下往上算。
导出的 CSV 为什么前面多了三个字节?
那是 UTF-8 BOM(EF BB BF)。Excel 靠它识别编码,没有它会把中文表头显示成乱码。用文本编辑器或程序读取时需要先跳过这三个字节,它们不是表格内容。
为什么两种空间算出来的差最大能到 73?
以黑压白为例,alpha 0.8 时 sRGB 得 51,线性光得 124,差 73;这不是算错,而是 0.8 处的编码值与光强偏离最大。alpha 到 1 时两套结果都归到前景色 0,差立刻变 0。