色觉测试关键在于控制颜色对比度与干扰项,而非单纯使用高饱和红绿;需用HSL/LAB手动降低色差、叠加灰阶噪点,并通过canvas精确绘制抗锯齿色块。

色觉测试的核心不是“画颜色”,而是控制颜色对比度和干扰项
直接用 #ff0000 和 #00ff00 做红绿色盲测试是无效的——真红绿色觉缺陷者看到的可能都是相近的黄褐色,关键在于用明度一致、色相差异被压缩的配色,并叠加噪点或纹理干扰。主流临床测试(如Ishihara)靠的是色块中数字/形状在色觉正常者眼里可辨、在缺陷者眼里“消失”。HTML实现必须绕过浏览器默认的高饱和渲染,用 hsl() 或 lab()(需JS转换)手动压低色差,再加灰阶噪点层。
用 canvas 绘制抗锯齿色块比纯CSS更可靠
CSS背景色在不同缩放、DPR下容易出现边缘混色,干扰判断;而 canvas 可精确控制每个像素的RGB值,并主动添加1–2%的随机灰度偏移模拟印刷噪点。示例关键逻辑:
const ctx = canvas.getContext('2d');
// 模拟红绿色盲视角下的“可辨色块”:用HSL微调色相,固定L=50,S=30
const normalRed = hslToRgb(0, 30, 50); // 真红
const normalGreen = hslToRgb(120, 30, 50); // 真绿
// 但测试图实际绘制时,用色觉缺陷模型转换后的近似值(如使用Machado算法)
const redForDeutranope = [142, 128, 95]; // 不是纯红,是缺陷者“以为的红”
const greenForDeutranope = [138, 128, 99]; // 缺陷者“以为的绿”
ctx.fillStyle = `rgb(${redForDeutranope})`;
ctx.fillRect(10, 10, 100, 100);
// 再叠加1%随机灰度噪点
for (let i = 0; i < 1000; i++) {
const x = 10 + Math.random() * 100;
const y = 10 + Math.random() * 100;
ctx.fillStyle = `rgb(${128 + Math.random()*10}, ${128 + Math.random()*10}, ${128 + Math.random()*10})`;
ctx.fillRect(x, y, 1, 1);
}用户交互必须禁用缩放和长按选中
手机端双指缩放会模糊色块边界,长按触发文字选择框会覆盖测试图。必须在 <head> 中加:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>body { -webkit-user-select: none; -moz-user-select: none; user-select: none; }</style>-
maximum-scale=1.0和user-scalable=no缺一不可,仅设initial-scale无效 - 部分安卓浏览器仍响应长按,需额外监听
touchstart并e.preventDefault() - 避免用
img标签加载预渲染图——解码压缩会改变色值,必须实时绘制
测试结果不能只靠“答对几题”,要记录设备环境
同一份测试在OLED屏和LCD屏上表现差异可达20%,iOS和Android默认色彩管理也不同。提交结果时至少附带:
立即学习“前端免费学习笔记(深入)”;
-
navigator.platform(识别iOS/Android/Desktop) -
window.devicePixelRatio(判断是否高PPI屏) -
screen.colorDepth(常见24或30,低于24需警告) - 用户是否开启系统“色彩校准”或“深色模式”(通过
window.matchMedia('(prefers-color-scheme: dark)'))
没这些上下文,任何“你可能是红绿色盲”的结论都缺乏依据。真正可靠的色觉筛查必须结合专业设备,网页版只是初筛提示工具。



















