三道闸,三个状态,不是一根轴。闸一管「缩略图里主字还认不认得出来」;闸二管「这块地面上,小字的对比度到底还剩多少」;闸三管「这张图的信息跨度,在目标比例集里装不装得下」。它们判的不是同一件事——缩略图绿了、地面绿了,比例集可能还是红的。
主字是墨迹高度,不是 font-size。判据是绝对像素 ≥25px(本机 300px 缩略图实测)与比例 ≥1/12 两条同时成立,外加对比度 ≥4.5。
三层分开报,不合成一个数:① 标称=两端色的 WCAG 比值,只在 α=1.0 处成立;② c50=α=0.5 处的有效对比度,小字该看这个数;③ 最终尺寸=折算到投放尺寸后的像素。缺 finalScale 一律 DECLARED-UNMEASURED——母版上的绿不作数。
| 层 | 读数 | 门槛 | 判定 |
|---|---|---|---|
| ① 标称 | — | — | — |
| ② c50 | — | — | — |
| ③ final | — | — | — |
| α(覆盖率) | 混合色 | 有效对比度 | 对门槛 |
|---|
标称是 α=1.0 的上确界,不是均值。梯子往下走一格,可能就掉出门槛——这才是小字的真实处境。
前两道闸判的是「缩略之后还认不认得出来」。这道闸判另一件事:信息跨度在目标比例集里装不装得下。S = yBot − yTop,B = W × h / w,S ≤ B 是充要条件,与带子的纵向位置无关——把整条带上下平移,S 不变。所以它判红时不能靠「挪一挪」救:那是构图问题,不是排版问题。
| 比例 | 判定 | 余量 B−S | 上出框 | 下出框 | 出框合计 | 带高 B | 带区间 [y₀, y₀+B] |
|---|---|---|---|---|---|---|---|
| 填入母版与信息边界后生成 | |||||||
为什么必须是二元组:cropSafe: y∈[875,1685] 单独出现时,读者分不清它是「对所有比例安全」还是「对这三个比例安全」——这两种意思在纸面上长得一模一样。分母写出来,别人才反对得动你。
式子的边界:源件写的是 B = W × 9 / r,那只对 N:9 族成立;它自己给的 1:1 → 1440、4:5 → 1800 是用 B = W × h/w 算的。本闸用通用式,N:9 时两者同值。照抄 ×9/r 去算 1:1 会得到 12960——那不是带宽,是错的数。
默认比例集是「声明集」,不是「平台实测集」:{1:1, 16:9, 4:5, 21:9} 来自交付约定与源件,各平台真实的裁切比、是否居中、超宽是否自动加边,UNVERIFIED。
全部走与用户输入完全相同的判定函数,页面加载时自动重跑。红臂不红就说明这条臂没有分辨力,页面会当场说出来,不改判据凑绿。
闸二的必红臂取「最小字号文本放到非设计地面上」:设计在深底的小字搬到 #FFFFFF、设计在浅底的小字搬到 #0B0D10,两个方向都必须红。另有一条 11px 浅底臂,断言 c50 落在 1.92 附近且整体被拒。
闸三的必红臂啃《刻名》v1 的实测值:W=1440、H=2560、信息 y∈[906,1615](S=709)放进 21:9(B=617)必须判红,并报出 92px 缺口。若这条臂判绿,说明这道闸只查了区间存在、没查比例集——那它测的是排版,不是装不装得下。旁边几条绿臂(16:9 / 1:1 / 4:5)保证它不是「见谁都红」;平移不变臂保证缺口只跟 S 与 B 有关,不跟位置有关;分母不全臂保证「有未算的比例时不许判绿」。
| 档 | 主字墨高 | 实测比 | 横笔画带 | 缩略后典型对比 | 判定 |
|---|---|---|---|---|---|
| 1/8 | 38px | 1/7.9 | 6 | 17.44:1 | 绿 |
| 1/12 | 25px | 1/12.0 | 6 | 16.18:1 | 绿 |
| 1/24 | 14px | 1/21.4 | 2 | 11.20:1 | 红 |
| 档 @ 高度 | 主字墨高 | 横笔画带 | 判定 |
|---|---|---|---|
| 1/12 @ 150px | 14px | 3 | 红 |
| 1/12 @ 200px | 17px | 3 | 红 |
| 1/12 @ 300px | 25px | 6 | 绿 |
| 1/12 @ 600px | 51px | 6 | 绿 |
| 1/8 @ 200px | 25px | 6 | 绿 |
判据取「横笔画带」:同一张图、同一个字,缩略图越矮,可分辨的笔画带越少。判定按绝对墨高 ≥25px(300px 高时即 1/12)。
| 案例(α=0.5) | 8-bit 进位 | canvas 实际落盘 | 差 |
|---|---|---|---|
| #FFFFFF × #000000(白底上界) | 3.9494 | 4.0041 | 0.055 |
| #0B0D10 × #E6E6E6 | 4.5241 | 4.4655 | 0.059 |
| #FFFFFF × #767676 | 1.9198 | 1.9408 | 0.021 |
| #0B0D10 × #FFFFFF(深底上界) | 5.3395 | 5.3395 | 0 |
前者按 round(bg·(1−α)+fg·α) 算,后者是把同一对色真的画到 canvas 上再 getImageData 读回来的像素值。只有在 v+f 为奇数、α 恰为 0.5 时两者会差 1 个 LSB——第 2 行的 4.52 因此不是像素值,而是算术进位值;真实像素是 4.47。
环境:Windows 10 19045 · HeadlessChrome 151 · canvas 2D · sRGB · getImageData 直读;闸一实测为同一台机器上的无头截图。
口径:c50=WCAG(blend(ground,fg,0.5), ground),混合在 8-bit sRGB 里做;标称=WCAG(fg, ground);final=sizePx×finalScale(或直接给的 finalPx)。
口径出处:《封面交付的第五层闸》 · 《栅格交付没有 prefers-color-scheme》 · 硬数来源 《对比度断言的字段契约 v0》