According to Wikipedia, when converting to grayscale representation of luminance, “one must obtain the values of its red, green, and blue” and mix them in next proportion: R:30% G:59% B:11%
Therefore white will have 100% luminance and yellow will have 89%. At the same time, green has as small as 59%. 11% is almost four times lower than 41% difference!
And even lime (#00ff00
) is not good for reading large amounts of texts.
IMHO for good contrast colors’ brightness should differ at least for 50%. And this brightness should be measured as converted to grayscale.
upd: Recently found a comprehensive tool for that on the web
which in order uses formula from w3 document
Threshold values could be taken from #1.4
Here is an implementation for this more advanced thing.
const RED = 0.2126;
const GREEN = 0.7152;
const BLUE = 0.0722;
const GAMMA = 2.4;
function luminance(r, g, b) {
var a = [r, g, b].map((v) => {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, GAMMA);
});
return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
}
function contrast(rgb1, rgb2) {
var lum1 = luminance(...rgb1);
var lum2 = luminance(...rgb2);
var brightest = Math.max(lum1, lum2);
var darkest = Math.min(lum1, lum2);
return (brightest + 0.05) / (darkest + 0.05);
}
console.log(contrast([255, 255, 255], [255, 255, 0])); // 1.074 for yellow
console.log(contrast([255, 255, 255], [0, 0, 255])); // 8.592 for blue
// note: minimal recommended contrast ratio is 4.5, or 3 for larger font-sizes
For more information, check the WCAG 2.0 documentation on how to compute this value.