构建您自己的颜色对比度检查器
色彩对比度不足是 Web 可访问性中最常见的问题之一。事实上,它是WebAIM Million分析中发现的最常见问题,占所有发现问题的 60% 以上。
网上有很多很棒的工具可以帮你检查颜色对比度,但这篇文章我将教你如何创建自己的工具。创建自己的颜色对比度检查器有很多好处:
- 这是一个小型编程项目;
- 它将帮助您了解颜色对比如何起作用;
- 它将允许一些创造性的过程。
但在进入编码部分之前,让我们先看一些理论......
什么是色彩对比?
这是一个很好的问题。
简单来说,两种颜色之间的对比度就是它们之间的差异。在网页设计中,你希望前景色和背景色之间有足够高的对比度,以便为有视力障碍和色觉障碍的用户提供更好的体验。
两种颜色之间的对比度使用我们将在下文中看到的数学函数计算。该计算结果的范围为 1 到 21(通常分别表示为 1:1 或 21:1)。如果两种颜色完全相同,则对比度为 1;白色和黑色之间的对比度最高,色轮中完全相反的颜色(互补色)的对比度也较高。
WCAG 颜色对比度要求是什么?
曾经有一个独特的对比度要求 4.5:1,但WCAG 2.1 定义了不同的颜色对比度要求,这些要求不仅取决于颜色,还取决于正在测试的元素的大小和重量或要实现的可访问性级别。
这很有道理。较小的文本需要比较大或加粗的文本更高的对比度。此外,为了达到更高的标准可访问性级别 (AAA),对比度必须高于其他级别 (AA)。
总体思路仍然是:文本颜色对比度必须为 4.5:1,但当文本较大(18 点或更高)或粗体(14 点或更高)时也有一些例外,在这种情况下,3:1 的颜色对比度足以达到 AA 级可访问性。
为了实现 AAA 级可访问性颜色对比度,常规文本的比例数字上升到 7:1,大文本的比例数字上升到 7:1。
成分 | AA级 | AAA级 |
---|---|---|
小文本 (<18pt 或 >=14pt 粗体) |
4.5:1 | 7:1 |
大文本 (>=18pt) |
3:1 | 4.5:1 |
什么是亮度?
在深入了解对比度及其计算方法之前,我们必须介绍亮度和相对亮度的概念:
[相对亮度是]色彩空间中任何一点的相对亮度,0 表示最深的黑色,1 表示最亮的白色。
计算相对亮度可能有点棘手,看起来很复杂,特别是如果我们检查WCAG 定义中包含的逻辑:
对于 sRGB 色彩空间,颜色的相对亮度定义为L = 0.2126 * R + 0.7152 * G + 0.0722 * B,其中R、G和B定义如下:
- 如果 RsRGB <= 0.03928 则 R = RsRGB/12.92 否则 R = ((RsRGB+0.055)/1.055) ^ 2.4
- 如果 GsRGB <= 0.03928 则 G = GsRGB/12.92 否则 G = ((GsRGB+0.055)/1.055) ^ 2.4
- 如果 BsRGB <= 0.03928 则 B = BsRGB/12.92 否则 B = ((BsRGB+0.055)/1.055) ^ 2.4 并且 RsRGB、GsRGB 和 BsRGB 定义为:
RsRGB = R8bit/255
GsRGB = G8bit/255
BsRGB = B8bit/255
“^”字符是指数运算符。(公式取自[sRGB]和[IEC-4WD])。
我知道。这段文字可能有点吓人,但一旦转换成代码,公式就没那么乱了。
对比度公式
这将是最后一步(至少是最后一个重要的计算步骤)。对比度公式也可以在 WCAG 定义中找到:
CR = (L1 + 0.05) / (L2 + 0.05),其中
- L1 是较浅颜色的相对亮度,并且
- L2 是较暗颜色的相对亮度。
它比亮度步骤简单得多……而且是检查 WCAG 定义的值之前的最后一步。所以,理论到此结束,代码开始。
构建颜色对比度检查器
现在我们已经回顾了有关颜色对比度、亮度及其计算方法的一般理论,我们可以开始构建颜色对比度检查器了。
它将是一个小巧简单的最小可行产品 (MVP),以后可以扩展。我们将使用 HTML 和 JavaScript(不使用框架)来开发它。
我们将设置两个输入框和一个按钮。输入框将采用有效十六进制颜色值的完整格式(例如 #003366)或简写格式(例如 #036)。按下按钮时,它会告诉我们颜色是否具有足够的对比度,是否符合可访问性。
翻译成 HTML 的内容可能如下所示:
<input type="text" id="color-1" value="#000000" />
<input type="text" id="color-2" value="#ffffff" />
<button>Calculate Color Contrast</button>
<div id="result"></div>
JavaScript 代码应该很简单。步骤如下:
- 将颜色分解为 RGB
- 计算每种颜色的相对亮度
- 计算对比度值
- 将值与 WCAG 要求进行比较
将颜色分解为 RGB
要将颜色从十六进制转换为 RGB,我们可以使用不同的方法或库。为了简单起见(并且将所有内容保留在原生 JS 中),我们选择使用hexToRgb
Tim Down 创建的函数:
function hexToRgb(hex) {
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
根据上面的 HTML,读取颜色并将其转换为 RGB 格式的 JavaScript 将是这样的:
// read the colors and transform them into rgb format
const color1 = document.querySelector("#color-1").value;
const color2 = document.querySelector("#color-2").value;
const color1rgb = hexToRgb(color1);
const color2rgb = hexToRgb(color2);
计算每种颜色的亮度
相对亮度计算算法在理论部分看起来很复杂,但一旦写出来就简单多了。例如,kirilloid 用 10 行代码总结了它:
function luminance(r, g, b) {
var a = [r, g, b].map(function (v) {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow( (v + 0.055) / 1.055, 2.4 );
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
我们可以将该公式与之前计算的 RGB 颜色一起使用,这样我们就能得到亮度:
// calculate the relative luminance
const color1luminance = luminance(color1rgb.r, color1rgb.g, color1rgb.b);
const color2luminance = luminance(color2rgb.r, color2rgb.g, color2rgb.b);
计算对比度
下一步是计算对比度。为此,需要指出的是,颜色的“顺序”无关紧要。这意味着,无论哪种颜色位于背景或前景,两种颜色的对比度都是相同的。
例如,白色与黑色的对比度将与黑色与白色的对比度相同。
正如我们在理论部分所解释的那样,亮度是一个介于 0 和 1 之间的值。这意味着亮度较高的颜色(最暗的颜色)将在公式中用作被除数:
// calculate the color contrast ratio
const ratio = color1luminance > color2luminance
? ((color2luminance + 0.05) / (color1luminance + 0.05))
: ((color1luminance + 0.05) / (color2luminance + 0.05));
至此,我们完成了对比度的所有重要计算。剩下的就是根据可访问性要求检查这些值。
与 WCAG 要求进行比较
我们有颜色对比度,并且 - 从您阅读并且没有跳过的理论来看 - 您知道最低 WCAG 要求是:
- AAA 级小文本为 0.14285(7.0:1)
- AA 级小文本为 0.22222(4.5:1),AAA 级大文本为 0.22222(4.5:1)
- AA 级大文本为 0.33333(3.0:1)
所以缺少的代码只是显示结果。为了保持之前的简单,我们可以这样做:
// show results depending on WCAG requirements
const result = `
AA-level large text: ${ratio < 1/3 ? 'PASS' : 'FAIL' }<br>
AA-level small text: ${ratio < 1/4.5 ? 'PASS' : 'FAIL' }<br>
AAA-level large text: ${ratio < 1/4.5 ? 'PASS' : 'FAIL' }<br>
AAA-level small text: ${ratio < 1/7 ? 'PASS' : 'FAIL' }
`;
document.querySelector("#result").innerHTML = result;
将所有这些步骤包装在一个公式中,并将其附加到按钮的单击事件后,我们的对比度检查器如下所示:
结果真的很简单,但也非常实用......现在真正的乐趣开始了。
增添一些活力
现在我们已经拥有了颜色对比度检查器所需的一切:读取颜色的输入以及计算对比度的逻辑……但这真的很基础。接下来就是发挥你的创造力的时候了。
您的检查器不必与网上其他的检查器一模一样。您可以添加自己的签名,并根据自己的需求进行调整。与 Web 开发中的大多数事物一样,唯一的限制就是您的想象力:
- 大多数在线颜色检查器只支持十六进制颜色,但您使用 HSL 颜色?那就把 HSL 添加到您的颜色检查器吧!或者使用工具/插件来解析任何颜色格式!
- 如果对比度不可用,想要提供建议和替代调色板吗?这对您的用户来说将非常有帮助!
- 动画、互动性等等?任何让它更易用、更有吸引力的东西都应该受到欢迎!
如果你最终开发出了自己的颜色对比度检查器,请在评论区分享。我很乐意看到。
例如,下面您可以找到我创建的一个颜色对比工具。它并不太花哨,我用原生 JS 开发,添加了输入 HEX 或 RGB 值的功能,并添加了动画效果,这样 SVG 角色就会根据可访问性级别或多或少地露出笑容。
文章来源:https://dev.to/alvaromontoro/building-your-own-color-contrast-checker-4j7o