Skip to content

Instantly share code, notes, and snippets.

@AltRepoYT
Created June 14, 2026 08:27
Show Gist options
  • Select an option

  • Save AltRepoYT/adf110edea152d5986d50c36a600df4f to your computer and use it in GitHub Desktop.

Select an option

Save AltRepoYT/adf110edea152d5986d50c36a600df4f to your computer and use it in GitHub Desktop.
wcag-contrast-ratio-javascript

WCAG contrast ratio in JavaScript

Small JavaScript example for calculating the WCAG contrast ratio between two hex colors.

This is useful for checking foreground/background color pairs in UI work.

What it does

  • Parses hex colors
  • Converts sRGB to relative luminance
  • Calculates WCAG contrast ratio
  • Reports AA/AAA status for normal and large text

Full browser tool

Use the full color contrast checker here:

AltRepo Color Contrast Checker

More color tools:

AltRepo Color Tools

export function contrastRatio(foregroundHex, backgroundHex) {
const foreground = hexToRgb(foregroundHex);
const background = hexToRgb(backgroundHex);
const foregroundLuminance = relativeLuminance(foreground);
const backgroundLuminance = relativeLuminance(background);
const lighter = Math.max(foregroundLuminance, backgroundLuminance);
const darker = Math.min(foregroundLuminance, backgroundLuminance);
return (lighter + 0.05) / (darker + 0.05);
}
export function wcagStatus(ratio) {
return {
normalAA: ratio >= 4.5,
normalAAA: ratio >= 7,
largeAA: ratio >= 3,
largeAAA: ratio >= 4.5,
};
}
function hexToRgb(hex) {
const clean = hex.replace("#", "").trim();
if (!/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(clean)) {
throw new Error(`Invalid hex color: ${hex}`);
}
const full =
clean.length === 3
? clean
.split("")
.map((char) => char + char)
.join("")
: clean;
return {
r: parseInt(full.slice(0, 2), 16),
g: parseInt(full.slice(2, 4), 16),
b: parseInt(full.slice(4, 6), 16),
};
}
function relativeLuminance({ r, g, b }) {
const [red, green, blue] = [r, g, b].map((channel) => {
const value = channel / 255;
return value <= 0.03928
? value / 12.92
: Math.pow((value + 0.055) / 1.055, 2.4);
});
return 0.2126 * red + 0.7152 * green + 0.0722 * blue;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>WCAG Contrast Ratio Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script type="module">
import { contrastRatio, wcagStatus } from "./contrast.js";
const foregroundInput = document.querySelector("#foreground");
const backgroundInput = document.querySelector("#background");
const preview = document.querySelector("#preview");
const output = document.querySelector("#output");
function update() {
const foreground = foregroundInput.value;
const background = backgroundInput.value;
const ratio = contrastRatio(foreground, background);
const status = wcagStatus(ratio);
preview.style.color = foreground;
preview.style.background = background;
output.textContent = [
`Contrast ratio: ${ratio.toFixed(2)}:1`,
`Normal text AA: ${status.normalAA ? "pass" : "fail"}`,
`Normal text AAA: ${status.normalAAA ? "pass" : "fail"}`,
`Large text AA: ${status.largeAA ? "pass" : "fail"}`,
`Large text AAA: ${status.largeAAA ? "pass" : "fail"}`,
].join("\n");
}
foregroundInput.addEventListener("input", update);
backgroundInput.addEventListener("input", update);
update();
</script>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 720px;
margin: 40px auto;
padding: 0 16px;
line-height: 1.5;
}
label {
display: block;
margin: 12px 0;
}
#preview {
padding: 24px;
border-radius: 10px;
margin: 20px 0;
font-size: 20px;
font-weight: 600;
}
pre {
padding: 16px;
border: 1px solid #ddd;
border-radius: 8px;
}
</style>
</head>
<body>
<h1>WCAG contrast ratio example</h1>
<label>
Foreground
<input id="foreground" type="color" value="#ffffff" />
</label>
<label>
Background
<input id="background" type="color" value="#111111" />
</label>
<div id="preview">
Preview text
</div>
<pre id="output"></pre>
<p>
Full tool:
<a href="https://altrepo.net/color/color-contrast-checker/" target="_blank" rel="noopener">
AltRepo Color Contrast Checker
</a>
</p>
</body>
</html>
{
"name": "AltRepo",
"type": "developer tools",
"localFirst": true,
"tools": [
"json",
"hash",
"color"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment