用js扫描p、span、label、button、a等元素的color与background-color,借助tinycolor2统一转rgb并调用getcontrastratio校验对比度,同时覆盖伪元素content文本,避免手动解析rgb格式及gamma误差。

怎么快速判断页面里哪些文本对比度不达标
别靠眼睛猜,也别等上线后被审计打回。直接用 JS 扫描真实渲染后的颜色值,重点盯住 p、span、label、button、a 这几类承载可读文本的元素——它们一旦设了 color 或 background-color,就必须验。
常见错误现象:
-
getComputedStyle(el).color返回格式不统一:IE 是rgb(100,100,100),Chrome 可能是rgb(100 100 100),带 alpha 时还可能是rgba(0,0,0,0.8) - 忽略
currentcolor、transparent、命名色(如darkblue)等非标准格式,导致解析失败 - 没处理伪元素(
::before/::after)里的content文本,而它们含“必填”“*”等关键提示时也计入可读文本范围
实操建议:
- 用
tinycolor2的new tinycolor(color).toRgb()统一转成 RGB 对象,省去手动正则和 gamma 反变换 - 对每个目标元素,先取
color和background-color,再调getContrastRatio(fg, bg);结果就标为高风险 - 加个简单开关:
if (window.matchMedia('(prefers-contrast: high)').matches),高对比模式下跳过检测,避免误报
为什么深灰文字配浅灰背景经常翻车
#333 和 #eee 看着有层次,但算出来对比度只有 ~2.1,远低于 AA 要求的 4.5。这不是设计品味问题,是亮度计算逻辑决定的。
核心原因在 luminance 计算:每个通道要先归一化(除以 255),再做 gamma 反变换——值 ≤ 0.03928 的直接 ÷12.92,否则用 ((val + 0.055) / 1.055) ** 2.4。这个步骤不能跳,浏览器不帮你做。
容易踩的坑:
- 直接拿 RGB 值套公式
(R1+G1+B1)/(R2+G2+B2)—— 完全错误,人眼对绿光更敏感,必须加权(0.2126R + 0.7152G + 0.0722B) - 把
#333当作#333333解析,漏掉中间两位,导致亮度偏差放大 - 背景用了渐变或图片,
getComputedStyle返回linear-gradient(...),没法当颜色用,得 fallback 到父级或 body 的background-color
表单控件哪些地方最容易漏检对比度
表单是重灾区,尤其以下三处常被忽略:
-
button:disabled:默认样式被覆盖后,很多人设成color: #aaa+background-color: #f5f5f5,实际对比度约 2.3,连 3:1(大文本最低要求)都不满足 -
input::placeholder:Chrome/Firefox 返回的 placeholder 颜色不是继承自color,得单独取getComputedStyle(input, '::placeholder').color -
label关联的input[type="checkbox"]或radio后面的文本:如果只给 input 设颜色,label 没显式设,可能用的是浏览器默认灰,和背景一混就糊了
实操建议:
- 检测时加上
document.querySelectorAll('button:disabled, input::placeholder, label'),别只扫常规文本节点 - 禁用态按钮优先用深色文字 + 浅色背景(如
#222on#e0e0e0),比浅灰文字靠谱得多 - 对 checkbox/radio,确保
label元素本身设置了明确color,而不是依赖父容器继承
要不要自己实现 luminance 计算函数
可以,但没必要从零写。真正复杂的是 edge case 处理:hsl()、named color、transparent、currentcolor、rgba 带透明度……这些都得兜底。
如果你项目已用 tinycolor2,直接 new tinycolor(color).getLuminance() 最稳;没引入的话,用 parseColor 函数至少得覆盖这几种:
- 十六进制:支持
#rgb、#rrggbb、#rrggbbaa - rgb/rgba 字符串:兼容逗号分隔、空格分隔、带百分比或 alpha
- 命名色:查表映射(
darkblue → #00008b) -
currentcolor:递归向上找最近的color声明
性能影响很小,但写错一行 gamma 反变换就会让整个对比度判断失效——比如把 0.04 错当成 >0.03928 处理,误差能到 20%。不如复用成熟逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











