Last active
April 5, 2017 22:51
-
-
Save cycomachead/eb12654eee868dc1e687758b2353b3a7 to your computer and use it in GitHub Desktop.
Testing W3C Color Contrast
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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