配色对比度检查器:一眼看清文字和背景谁看不清

前端调色最容易被忽略的坑,是「看起来还行,但视力不好的人根本读不清」。这个工具分别设置文字色和背景色,按 WCAG 公式实时算出对比度,再标出能不能过 AA/AAA 的大号文字与普通文字标准;取色器、随机配色都有,不够达标的配色还能自动在 HSL 里找最接近的可通过颜色。先看成品,再讲这个网页怎么用一段提示词做成单文件应用并部署上线。

这个工具做什么

它把「WCAG 对比度检查器」做成一个零依赖的单页应用:

  • 文字色 / 背景色分开设置:两个颜色输入框加取色器,改一个数立刻重算。
  • 四项标准一并显示:AA 普通文字、AA 大号文字、AAA 普通文字、AAA 大号文字,过没过一眼看。
  • 实时预览:中间示例文字直接用你选的配色渲染,所见即所得。
  • 达标建议:对比度不达标的配色,一键在 HSL 空间找到最接近的可通过颜色。
  • CSS 直接复制 :生成 color / background-color 两行代码,一键复制。
  • 随机配色:拿不定主意时先随机一组,再手动微调。

准备环境:进入码道CodeArts

本文用 CodeArts 的 WebUI 版来演示。先进入 CodeArts 并开通体验版,不需要装任何软件,浏览器就能用:

进入 CodeArts:developer.huaweicloud.com/codeartsco....

开通后有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

进入 AI 开发者空间

  1. 浏览器打开 devstation.developer.huaweicloud.com/aidevspace?...
  2. 弹窗「请选择要进入的版本」→ 点击 体验版
  3. 首次使用会跳到华为云登录页,扫码登录一次,后续浏览器会话复用
  4. 弹窗「临时凭据自动配置」→ 点击 同意,沙箱自动创建

进入 AI 开发者空间主界面后,先等左侧菜单加载出来,再找到 CodeArts ,点击它右侧的浏览器图标,打开码道 WebUI 对话窗口:

打开后码道 WebUI 会先和你打招呼,下方就是需求输入框:

小贴士:体验版沙箱 3 小时后自动重置,生成完记得把 index.html 下载保存。

任务描述

在码道 WebUI 输入框粘贴以下需求,回车发送:

text 复制代码
开发一个「配色对比度检查器」网页应用:用户分别设置文字颜色和背景颜色,应用实时计算 WCAG 对比度比值,并按 AA/AAA 的大号文字/普通文字标准显示通过还是失败;支持取色器、随机配色,能给出达标配色建议并复制 CSS 颜色代码;界面简洁美观,单个网页即跑即玩。完成后部署成可访问的网页应用,并告诉我访问地址。

这轮码道具体做了什么

不是复述通用 AI 能力,而是它在这个项目里的实际动作:

  • 在 /workspace/color-contrast-checker 下创建单文件 index.html,把颜色解析、亮度计算、对比度公式、达标建议和复制逻辑都放进一个文件,无第三方依赖。
  • 写入后做 JS 语法检查,纠正笔误再启动服务。
  • 探测空闲端口、用 python3 -m http.server 启动,自检 HTTP 200 后给出预览地址。

代码亮点

以下是 index.html 里值得关注的设计思路和实现细节。

1. 对比度本質是「相对亮度」的距离

WCAG 对比度不是两个 RGB 直接相减,而是先把颜色转到线性空间的相对亮度,分量各自做 gamma 校正,再按人眼敏感度加权:

javascript 复制代码
function relLuminance(rgb) {
  function chan(c) {
    c /= 255;
    return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  }
  return 0.2126 * chan(rgb.r) + 0.7152 * chan(rgb.g) + 0.0722 * chan(rgb.b);
}

function contrastRatio(hex1, hex2) {
  var a = hexToRgb(hex1), b = hexToRgb(hex2);
  if (!a || !b) return 0;
  var l1 = relLuminance(a), l2 = relLuminance(b);
  var hi = Math.max(l1, l2), lo = Math.min(l1, l2);
  return (hi + 0.05) / (lo + 0.05);
}

红色权重只有 0.2126,绿色最高 0.7152,所以同样肉眼差不多的两对颜色,计算出的对比度可能差很多。

2. 四项标准是配置,不是硬编码判断

javascript 复制代码
var STANDARDS = [
  { key: 'aa-n', name: 'AA · 普通文字', min: 4.5 },
  { key: 'aa-l', name: 'AA · 大号文字', min: 3.0 },
  { key: 'aaa-n', name: 'AAA · 普通文字', min: 7.0 },
  { key: 'aaa-l', name: 'AAA · 大号文字', min: 4.5 }
];

渲染时循环这份配置,和算出的 ratio 比较,过关显示绿、不过关显示红。要加新标准只要动数组,渲染逻辑不用改。

3. 辅助色同步显示 RGB / HSL

取到的颜色不是黑箱。setMeta 把 HEX 转成 RGB 再转 HSL,两个色值同时展示,改颜色时能直观看到亮度、饱和度怎么变:

javascript 复制代码
function setMeta(el, hex) {
  var rgb = hexToRgb(hex);
  if (!rgb) { el.textContent = '无效颜色'; return; }
  var hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
  el.textContent = 'RGB(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')  ·  HSL(' +
    Math.round(hsl.h) + ', ' + Math.round(hsl.s) + '%, ' + Math.round(hsl.l) + '%)';
}

4. 达标建议在 HSL 里搜最近可用色

对比度不够时,直接把原色搬到 HSL 空间,固定色相和饱和度、从 0 到 100 逐步试亮度,找到第一个能满足目标对比度的亮度,取「离原亮度最近」的结果:

javascript 复制代码
function findAccessible(baseHex, targetHex, targetRatio) {
  var base = hexToRgb(baseHex);
  var hsl = rgbToHsl(base.r, base.g, base.b);
  var best = null, bestDist = Infinity;
  for (var l = 0; l <= 100; l += 1) {
    var rgb = hslToRgb(hsl.h, hsl.s, l);
    var hex = rgbToHex(rgb.r, rgb.g, rgb.b);
    var r = contrastRatio(hex, targetHex);
    if (r >= targetRatio) {
      var dist = Math.abs(l - hsl.l);
      if (dist < bestDist) { bestDist = dist; best = hex; }
    }
  }
  return best;
}

亮度步进 1% 搜索,虽然只是近似最优,但足够快,也基本能保住原配色的观感。

直接下载试玩

本次生成的项目就是单文件 index.html,没有第三方依赖,把文件保存到本地后双击用浏览器打开即可运行。源码同步到公开 Demo Park 仓库:

总结

配色对比度检查器把「能不能看清」拆成两个可计算的环节:相对亮度用 WCAG 的 gamma 校正公式,达标判断用四项标准配置循环。达标建议没有上复杂的搜索算法,只在 HSL 亮度轴上做 1% 步进,换来的是即时反馈和小体积。后续可以继续加「保存配色组」「历史记录对比」「从图片提取主色」,或者把大号文字的口径做成可配置。

相关推荐
星栈2 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技2 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户47949283569153 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马5 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng6 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
清晨Coding6 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
鶴哥只手遮天7 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
FungLeo9 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构
Lank_M12 小时前
白底都占八成,PNG 为何只在图表页赢过 JPG
前端
张一凡9312 小时前
给 Coding Agent 加一道"架构闸门":Jin 是如何做到"先审架构、再写代码、不漂移"的
前端·后端·agent