知微工作室 · 自家踩完坑做出来的工具

肉眼逐屏看不全的背景硬缝与低对比文字,
让真浏览器逐像素扫出来

驱动你本机已装的 Edge 或 Chrome,按真实视口逐屏截图,用像素判定「文档态硬接缝」与逐行合成后的文字对比度, 再靠两轮反证排掉误报,最后交一份能直接转发的 HTML / PDF 证据报告—— 每个问题都带屏幕坐标、台阶量级和是哪个元素画的。

0第三方依赖(Node 18+ 直接跑)
3端视口默认同扫:桌面 / 平板 / 手机
66项真机自测,连续三轮 66 通过 / 0 失败
9个自家官网真实缺陷由它挖出并修掉

它替掉的是三件很费人、又最容易漏的事

做深色 + 渐变背景的站时被这几个问题反复咬过,市面上的截图对比工具又接不住——所以我们自己写了一个。

◱

背景接缝「只在滚动时出现」

固定视差层、分段背景、辉光裁断,单屏截图完全正常,滚到某一屏才留下一条明度台阶。人工翻屏要么看不见,要么看见了不知道是哪层画的。

  • 逐屏连续采样整页,跨屏也能定位到文档 Y 坐标
  • 量级用「亮度台阶」表示,能比较严重程度
⊘

自动化工具误报成灾

截图对比类工具把正常渐变、卡片投影、1px 分割线全报成缺陷,客户第一版就被误报劝退。误报比漏报更贵。

  • 关掉装饰层复扫:台阶消失 ⇒ 判为背景自身,不算缺陷
  • 同一屏幕行在多数屏命中 ⇒ 固定背景,剔除
  • 留白列被内容压住 ⇒ 降级为提示,不判失败
◔

对比度「算错了还以为算对了」

文字压在多层半透明 + 渐变底上,静态样式表算不出真实前景色;Lighthouse 只看 DOM 属性,看不出合成结果。

  • 取截图上文字所在像素的实际背景,逐层合成透明度后再算
  • 正文 ≥4.5、大字(≥24px)≥3.0,逐段给结论

一轮审计跑完,机器替你做了这些

整条链路只依赖本机浏览器的 CDP 协议:PNG 解码、WebSocket 客户端都是手写的,不装任何包。

起真机实例分配空闲端口与独立临时 profile,显式给定窗口尺寸(默认值会在截图上留下假台阶)。
冻结动效注入 CSS 关掉过渡与动画、让入场元素直接可见,等过场退场后再采样。
逐屏采样按视口滚动截图,取左右留白列的逐行亮度,找「一行之内跨过去」的硬边界。
两轮反证关掉装饰层复扫一遍;再按屏幕行分布判是不是固定背景自身。
成因归因不依赖历史基线:在当前 DOM 里找边界两侧贴着的元素,直接指出肇事选择器与它的光源。
对比度探针逐段取真实合成背景像素算比值,标出不足段落及其坐标。
证据报告HTML(截图上直接画标注框)+ 可选 PDF;输出前自动脱敏并自检。
退出码有失败项回非 0,可直接进 CI 当门禁卡口。

启动这一层为什么单独说

headless 浏览器最容易在客户机器上翻车的就是「偶发秒退」和「失败后留一堆孤儿进程」。我们把这三条钉死:

  • 端口必须 127.0.0.1 与 ::1 两个协议栈都探测为空闲才使用(IPv4 被占时浏览器会静默改绑 IPv6,进而连到别人的实例)
  • 临时 profile 目录由系统保证唯一,启动前清残留单例锁
  • 秒退自动换端口 + 换 profile 重试;每一条失败路径与 Ctrl+C / 崩溃都会杀进程树、删目录,不留孤儿

跑一次的代价

全部在你本机完成,不上传页面、不留存数据,也不需要什么服务:

  • 单页三端审计:约 1–3 分钟(视页面长度与动效)
  • 报告自含截图,可整份转发,不需要再打开原站
  • 纯命令行,能挂进流水线做发版门禁

判据口径全公开

所有阈值都从代码里抽出来按档位配置,每个数字都标明是「量出来的」还是「拍的」;拍的会在配置里写 TODO, 等首批真实样本回来复核。我们宁可让你看到判据本身,也不给一个黑箱分数。

判据口径怎么来的
文档态硬接缝(失败级) 亮度台阶 ≥ 8 级,且一行内跨过去(锐度 ≥0.8) 真缺陷实测 12 / 29 / 37 级,逐行噪声 2–6 级 — 阈值取在两者之间
同一条但仅提示 3–8 级(深色档)/ 2–8(浅色)/ 1.5–6(纯色) 星云留白里肉眼分辨不出的量级不外判,避免误报
误报闸 ①:背景自身 同一屏幕行在 ≥50% 的屏命中 ⇒ 剔除 固定视差 / 网格层是「看着像缺陷」的主要来源
误报闸 ②:留白被压 左右留白列被非内容块覆盖率过高 ⇒ 降级为提示 组件撑满整宽的窄屏,「只看留白列」前提不成立
内容边缘不算污染 满屏宽(≥95% 视口)的块不计入留白污染 它的边压在视口边界上,计入等于自废判据、把真缺陷降成提示
文字可读性 正文 ≥ 4.5,≥24px 大字 ≥ 3.0 对齐 WCAG AA;背景取截图上该像素的合成结果
成因归因 当前 DOM 元素边界贴合硬缝(≤12px)+ 宽度占比判据 不需要历史基线,第一次跑就能给出「谁的 CSS」

说明:工具不做「打分」。输出的只有具体位置(文档 Y 坐标 / 屏幕行)、量级、肇事元素和它为什么像缺陷的成因, 修与不修由人判断——把不确定交给算法,是把误报换成另一种形式。

三档内置阈值 + 自动选档

同一组数字搬到浅色纯色站就会大面积误报——所以判据分档。也可以用 --profile my.json 只覆盖你要改的字段。

适用

深色底 + 固定视差背景 + 半透明卡片的站。这是我们标定这一档的站点类型:带视差光斑、辉光分割线、多层 position:fixed 背景层。

失败线 8 级真缺陷实测 12/29/37 级,全部落在其上
提示线 3 级星云留白里肉眼分辨不出
最小台阶 1.2低于此视为逐行噪声直接不看
反证关掉装饰层视差层 / 网格 / 光斑共 6 类选择器

这一档修掉的真实案例

自家官网的面包屑区被扫出 +37 级硬带:分割线辉光在裁断处留下一条明度台阶,肉眼在深色底上几乎看不出来,滚动时却会一闪而过。

示意图:三段背景的亮度差异被判定为两条硬边界,归因指向分割线容器自身。

适用

白 / 浅灰底、实色卡片、少量渐变的内容站。背景本身干净,判据可以比深色档更严。

最小台阶 0.8浅底噪声低,能看更小的台阶
锐度 0.85收紧:浅色站的正常阴影过渡更容易被当成台阶
提示线 2 级失败线仍是 8 级 — 第一版对客户不外扩失败判定
反证关掉装饰层模糊底、hero 渐变、deco/glow 类元素

这一档的验证方式

自带两个真机夹具:一页「干净对照页」(满屏渐变 + 卡片投影 + 1px 亮线),一页「埋点缺陷页」(人为画出硬带、渐变字配黑阴影、浅灰正文)。

  • 干净页:0 失败、0 提示、文字全部达标(不许误报)
  • 埋点页:埋的几个缺陷全部被抓到,且能归因到埋进去的那个元素

适用

整站单一底色、无渐变无纹理。理论上留白列应当完全平:任何台阶都是元素画的。

失败线 6 级纯色底上 6 级已经看得出来(标注为 TODO,待真实样本复核)
窗口 6 行纯色底不需要大窗口平滑
提示线 1.5 级判据最严,误报面也最小
反证关掉装饰层pattern / noise / deco 类元素

诚实说明

这一档的失败线是拍板值,不是实测标定值——配置文件里就直接写了 TODO。等首批客户样本回来复核再收紧或放宽。我们不会把它说成「行业阈值」。

自定义档位支持 "extends": "light" 深合并,只写你要改的字段即可,其余继承。

先拿自己开刀:可复核的自检数据

下面每一行都是这台机器上跑出来的结果,不是宣传数字。工具对外之前,验收标准是「先扫自己扫得出问题」。

真实案例 · 自家官网

知微工作室官网经本工具复测

桌面 1440 / 平板 834 / 手机 390 三端逐屏采样,含 116 段正文对比度探针。

  • 文字可读性:0 不合格
  • 文档态失败级硬缝:0 条
  • 仅提示项:1 条(定价页 +4.88 级,低于 8 级失败线,肉眼不可分辨)
  • 此前同一工具链在官网共挖出并修掉 9 个真实渲染缺陷,含上文那条面包屑 +37 级硬带

这一档数据的意义在于「修完之后确实扫不出来」,而不是「扫得出一堆问题」。修完复扫为 0,是这条链路有效性的证据。

回归自测 · 套件

真机套件连续三轮

离线逻辑 + 真机夹具 + 启动稳健性三项合并计数。

范围结果说明
离线 + 真机夹具66 ✓ / 0 ✗连续三轮一致
其中启动稳健性12 ✓ / 0 ✗端口占用 / 秒退重试 / 并发 / 无孤儿
线上三端回归62 ✓ / 0 ✗与内部标定值对齐,确认没 regression
跑完残留 headless 进程0按命令行特征过滤,含崩溃路径

「跑完不留孤儿」这一条以前是写在注释里的承诺,没兑现:实测残留 35 个临时 profile 目录。现在由回收表与退出钩子强制,且新增的秒退重试路径实测 0 新增残留。

已证伪的三类假阳性

  • 「背景接缝」实为未显式设窗口尺寸,headless 默认 800×600 的合成器台阶
  • 「低对比」实为把入场动画未定格的半透明帧当成了最终态
  • 「硬缝」实为卡片 1px 亮边——内容边缘,不是背景问题

三类都进了判据层做长期防线,不是靠人工挑刺绕过。

不做的判断

  • 不做主观美感评分,只报可量测的像素事实
  • 不替你决定「这条要不要修」,只给位置、量级、成因
  • 不接需要登录态的页面:只审计免登录可访问的 URL

已知边界

  • 只支持带 CDP 的浏览器(Edge / Chrome),Firefox、Safari 不支持
  • PDF 走浏览器打印,长报告分页位置不如人工排版;对外交付以 HTML 为准
  • 重动效页面需调等待时长与采样屏数参数

报告长什么样

一份自包含 HTML:结论区给「有没有要修的」,证据区把截图直接标注上问题位置,归因区写清是谁的 CSS。可整份转发给客户,也可以另存 PDF。

 视觉 QA 证据报告(节选示意,非真实客户数据)
失败 · 文档态硬接缝 y=1873 台阶 +29.4

跨屏边界处亮度台阶超过失败线,反证轮关闭装饰层后仍存在 ⇒ 非背景自身。

归因:section.cta-band::before(辉光渐变在容器裁断处留下台阶)

失败 · 文字对比度不足 3.12 y=946

正文段落合成后前景/背景比值低于 4.5;背景为两层半透明叠渐变。

归因:.hero p 颜色 #5d7fa6 落在 .veil 之上

提示 · 疑似硬缝 y=3203 台阶 +4.88

低于失败线(8 级),深色留白中肉眼不可分辨。默认不外判,供排查参考。

通过 · 手机视口 390×844

组件轮廓被判为背景级别已撤销;留白列被内容压住,按口径降级为提示。

报告里必定包含的四件事

  • 位置:文档 Y 坐标 + 所属视口,不用你再去翻是哪一屏
  • 量级:亮度台阶级数 / 对比度比值,可比较、可复查
  • 成因:贴合边界的内容元素选择器,及其被判为背景/内容/固定的推理依据
  • 证据:截图上画出标注框,不靠文字描述让你脑补

脱敏是产线的一部分

报告渲染前会扫一遍内部标识与本地路径,命中即拒绝输出——所以这份文件可以整份发给客户、也能进公开工单。

想要针对你自己站点的一份真实样例报告?发邮箱地址即可,内测期先免费出一份看看合不合用。

命令与流水线接入

没有配置文件要填、没有服务要起:一条命令出一个 URL 的三端结论。

# 三端审计 + HTML 报告
node index.js audit https://example.com

# 自动按站点特征选档,顺带导出 PDF
node index.js audit https://example.com \
     --profile auto --pdf

# 只看背景接缝 / 只看文字可读性(终端文本)
node index.js seams https://example.com
node index.js probe https://example.com

# 批量:一个 URL 一行,逐页出报告 + 终端汇总
node index.js batch urls.txt --out ./reports

# 列出内置档位及其阈值
node index.js profiles
# CI 门禁:有失败项就退非 0
node index.js audit https://staging.example.com \
     --json --views desktop || exit 1

环境要求

  • Windows / macOS / Linux,Node 18 以上
  • 本机已装 Edge 或 Chrome(Firefox 无 CDP,明确不支持)
  • 零 npm 依赖:PNG 解码与 WebSocket 客户端都是自带实现
  • 浏览器路径可用环境变量指定,无需改代码

不联网上传任何页面内容:审计在被测页面与你本机浏览器之间完成。

内测期怎么开始

现在不做正式定价公示。首批客户跑通、拿到真实误报/漏报样本之后,档位与价格才敢定死。

首批内测体验价
¥9.9 / 页起

单页三端(桌面 / 平板 / 手机)审计 + 一份可转发的证据报告,当天出。

  • 含判据口径说明,告诉你为什么某条只算提示
  • 报告不满意全额退,不用解释理由
  • 内测期反馈缺陷样本可换多页额度

多页 / 整站 / 接入 CI 的报价邮件里按页面数说,不写死高价,也不搞阶梯话术。

邮箱询价 · cqsj6667@agent.qq.com

也可以只买「怎么判」这一层

如果你已经有自己的巡检脚本,想要的是判据与阈值口径(含两道反证闸的实现思路),我们可以只给一份《判据口径与阈值标定说明》,不含跑站。

这一项按咨询计,邮件说清你的技术栈即可给结论。

不适合本工具的活

  • 需要登录态、支付流程内页的审计
  • 主观视觉风格评估、竞品美学对比
  • 要求给出「设计分数」的报告书
  • Safari / Firefox 专属渲染问题

这几种我们不接——不是客气,是确实给不出可信结论。

几个一定会被问到的问题

和 Lighthouse / 截图对比工具比,差别在哪?

Lighthouse 的对比度检查读 DOM 样式属性,看不出文字底下压了几层半透明和渐变之后的真实像素;本工具直接从截图取背景像素再算比值。截图对比类工具需要一个「正确基线」,一旦没有基线就只能报「这里不一样」;本工具不依赖基线,靠当前 DOM 的元素边界贴合来指认肇事元素。

更关键的是误报处理:关掉装饰层复扫 + 屏幕行分布两道闸,把「看起来像缺陷的背景」和「页面画的硬缝」分开。

为什么必须用真浏览器?Playwright 之类不是更省事?

结论要能拿去和客户争,就必须是被测页面在真实渲染管线里跑出来的样子:合成器分层、亚像素取整、滤镜裁断这些在 DOM 里推不出来。我们选 CDP 直连本机已装浏览器,是为了不再引一层依赖,也避免「装了包但客户机器装不上」——这是对外产品最容易死的地方。

报「0 条失败」我怎么信?

三条路都可以自查:一是报告里每条提示项都给坐标与量级,可以自己滚到那一屏看;二是判据口径在本页全部公开(含失败线与两道闸的比值),不存在黑箱;三是自带两个真机夹具——干净页必须 0 误报、埋点页必须全抓到,你拿到工具第一件事就可以跑这两个夹具验证有效性。

会不会把我站上未公开的内容传走?

不会。工具在你本机驱动你本机的浏览器,截图与报告都写在本地目录,全程没有第三方服务、没有上报。要发版前,报告和源码还各做一次脱敏自检,命中内部标识就直接拒绝输出。

能接进 CI 吗?跑一次多久?

能。有失败项返回非 0 退出码,加 --json 出机器可读结果;只用文本输出做卡口也可以。单页三端约 1–3 分钟,取决于页面长度与动效多少;批量模式一页一份报告,最后给终端汇总。

阈值是不是拍脑袋?

深色档与浅色档的失败线来自实测标定(真缺陷 12/29/37 级、噪声 2–6 级),提示线按「肉眼分辨不出就不外判」定;纯色档的失败线 6 级是拍板值,配置文件里直接写了 TODO 等真实样本复核。每个数字的来历在配置注释里。

把你站点上那条「滚动时才出现的缝」交出来看看

发站点地址到邮箱,内测期先出一份真实报告给你看判得准不准;不合适的判据我们可以调档。

cqsj6667@agent.qq.com

24 小时内响应 · 数据不留存 · 报告可整份转发 · 知微工作室主站