Skip to content

Instantly share code, notes, and snippets.

@cycomachead
Last active April 5, 2017 22:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cycomachead/eb12654eee868dc1e687758b2353b3a7 to your computer and use it in GitHub Desktop.
Save cycomachead/eb12654eee868dc1e687758b2353b3a7 to your computer and use it in GitHub Desktop.
Testing W3C Color Contrast
/*
Color Contrast
Implement WCAG's Color Contrast formula
Designed to take in hex color codes:
ratio('000000', 'FFFFFF') → 21 is the defined ratio between white and black
*/
// Convert hex to number
// Decimal should be a float [0, 1.0]
let hex2int = (str) => parseInt(str, 16);
let hex2dec = (str) => parseInt(str, 16) / 255.0;
let r = (color) => hex2dec(color.substring(0, 2));
let g = (color) => hex2dec(color.substring(2, 4));
let b = (color) => hex2dec(color.substring(4, 6));
let rInt = (color) => hex2int(color.substring(0, 2));
let gInt = (color) => hex2int(color.substring(2, 4));
let bInt = (color) => hex2int(color.substring(4, 6));
// W3C Contrast Formula
// https://www.w3.org/TR/WCAG21/relative-luminance.xml
// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
let luma_ratio = (l1, l2) => (l1 + 0.05) / (l2 + 0.05);
let s = (val) => val <= 0.03298 ? val / 12.92 : Math.pow((val + 0.055)/1.055, 2.4);
let relative_luma = (r, g, b) => (0.2126 * s(r)) + (0.7152 * s(g)) + (0.0722 * s(b));
let luma_color = (color) => relative_luma(r(color), g(color), b(color));
// Return a color ratio in [1, 21]
// This checks which color is "brighter"
function ratio(color1, color2) {
let luma1 = luma_color(color1);
let luma2 = luma_color(color2);
if (luma1 > luma2) {
return luma_ratio(luma1, luma2);
} else {
return luma_ratio(luma2, luma1);
}
}
function samples() {
let white = 'FFFFFF';
let black = '000000';
let teal = '1CA9C4';
console.log('Teal on White', ratio(teal, white));
console.log('Teal on Black', ratio(teal, black));
console.log('White on Black', ratio(white, black));
}
/*
W3C Alert Spec Color Differences
https://www.w3.org/TR/AERT#color-contrast
*/
let brightness = (color) => (rInt(color) * 299 + gInt(color) * 587 + bInt(color) * 114) / 1000;
function maxDiff(c1, c2) {
return (Math.max(rInt(c1), rInt(c2)) - Math.min(rInt(c1), rInt(c2))) +
(Math.max(gInt(c1), gInt(c2)) - Math.min(gInt(c1), gInt(c2))) +
(Math.max(bInt(c1), bInt(c2)) - Math.min(bInt(c1), bInt(c2)));
}
function isPassing(color1, color2) {
return Math.abs(brightness(color1) - brightness(color2)) >= 125 && maxDiff(color1, color2) >= 500;
}
console.log('isPassing? Black White', isPassing('000000', 'FFFFFF'));
console.log('isPassing? Black Teal', isPassing('000000', '1CA9C4'));
console.log('isPassing? Teal White', isPassing('1CA9C4', 'FFFFFF'));
if (typeof module !== 'undefined') {
module.exports = ratio;
module.exports.samples = samples;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment