Last active
November 14, 2022 12:59
-
-
Save TheWorstProgrammerEver/d52c0118e84a9fc4161c2c66404ad736 to your computer and use it in GitHub Desktop.
WCAG Colour Contrast Checker in JS.
This file contains hidden or 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
// https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio | |
const contrastLightAndDark = (lighter, darker) => (lighter + 0.05) / (darker + 0.05) | |
const relativeLuminance = (r, g, b) => 0.2126 * C(r) + 0.7152 * C(g) + 0.0722 * C(b) | |
const C = c => { | |
const colourScalar = c / 255 | |
return colourScalar <= 0.03928 | |
? colourScalar / 12.92 | |
: Math.pow(((colourScalar + 0.055) / 1.055), 2.4) | |
} | |
const colourContrast = (c1, c2) => { | |
let l1 = relativeLuminance(c1.r, c1.g, c1.b) | |
let l2 = relativeLuminance(c2.r, c2.g, c2.b) | |
return l1 > l2 | |
? contrastLightAndDark(l1, l2) | |
: contrastLightAndDark(l2, l1) | |
} | |
const hexToRgb = hex => { | |
const rgb = hex | |
.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) => '#' + r + r + g + g + b + b) | |
.substring(1).match(/.{2}/g) | |
.map(x => parseInt(x, 16)) | |
return { r: rgb[0], g: rgb[1], b: rgb[2] } | |
} | |
const colourContrastHex = (hex1, hex2) => { | |
const c1 = hexToRgb(hex1) | |
const c2 = hexToRgb(hex2) | |
return colourContrast(c1, c2) | |
} | |
// WCAG 2.1 Success Criteria | |
const isLargeText = (fontSizePt, isBold) => | |
fontSizePt >= 18 || isBold && fontSizePt >= 14 | |
const successCriteria = { | |
['1.4.3']: { largeTextContrast: 3.0, normaltextContrast: 4.5 }, | |
['1.4.6']: { largeTextContrast: 4.5, normaltextContrast: 7.0 } | |
} | |
const satisfies = (successCriterion, fontSizePt, isBold, foregroundColourHex, backgroundColourHex) => { | |
const { largeTextContrast, normaltextContrast } = successCriteria[successCriterion] | |
const contrast = colourContrastHex(foregroundColourHex, backgroundColourHex) | |
return contrast >= normaltextContrast || isLargeText(fontSizePt, isBold) && contrast >= largeTextContrast | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment