半透明文本需按实际合成色计算
别名: 透明度对比度 · alpha blending · 合成色
概念解释
样式里写着 color: black 且对比「按黑色」去过,并不等于屏幕上的字是黑色。带透明度的文本必须按叠在背景上之后的合成色来算对比:前景按 alpha 与底色混合,得到的才是眼睛和测点工具真正看到的 RGB。40% 不透明度的黑字铺在白底上,合成接近中灰,比值会掉到常用下限以下。检查器如果只读样式表里的不透明色号,会给出假通过。
机制
alpha 合成是线性混合:C_out = C_fg × α + C_bg × (1 − α)。对比公式吃的是两端的相对亮度,不是「设计意图里的那个纯色」。把层级靠降低透明度来做,等于在未知背景上把前景往底色里掺水;α 越低,比值越接近 1。
第二层是多层叠加。字本身半透明,底下卡片也是半透明,再底下是页面底色,检查器读到的 color 和 background-color 都不是最终像素。mix-blend-mode、毛玻璃、遮罩会让合成进一步偏离色板。占位符、次要说明、禁用态最常被拿去「变淡」,也最常在合成之后翻车。字号字重决定用哪条下限,合成色决定拿什么值去比——两件事不要混成一次取色。
怎么研究
对渲染结果做像素取样(截图取色、无障碍对比扫描里的「实际像素」模式),与 getComputedStyle 读到的 CSS 色并排。专门做一组「色板对比合格、加上 opacity 之后失败」的对照页。
自变量:前景 alpha、背景亮度、中间层是否也透明。 因变量:色板比值、合成后比值、两者差值、误判为通过的次数。
自动化规则如果只解析颜色字符串、不合成,会系统性漏检。半透明叠在照片或渐变上时,合成色还会随位置变,需要另做保底,不能只取一个点当代表。
边界
不透明文本在纯色底上,合成等于色板,这一条不增加新工作。打印和导出 PDF 若把透明度拍扁,要以输出件为准。深色模式会改底色,同一 alpha 在浅底过、在深底可能不过,要两套都合成。文字阴影、描边会在字形边缘制造另一圈合成色,取色要取笔画内部,不要取抗锯齿边。
怎么落地
- 层级用更浅的不透明色来做,不要用降低 alpha 冒充浅灰。
- 必须用透明度时,在目标底色上把合成 RGB 算出来(或截图取色)再跑对比。
- 卡片、浮层、毛玻璃上的字,把中间层一并合成,禁止只检查最底层色板。
- 验证:截一屏,对字形内部像素和紧邻背景像素取色算比值;对照样式面板里的不透明色号,任何「色板过、像素不过」都记为缺陷。把透明度开到 0 再开回来,确认测的是叠上之后的那一帧。