Skip to content

Instantly share code, notes, and snippets.

@TheWorstProgrammerEver
Last active November 14, 2022 12:59
Show Gist options
  • Save TheWorstProgrammerEver/d52c0118e84a9fc4161c2c66404ad736 to your computer and use it in GitHub Desktop.
Save TheWorstProgrammerEver/d52c0118e84a9fc4161c2c66404ad736 to your computer and use it in GitHub Desktop.
WCAG Colour Contrast Checker in JS.
// 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