WCAG contrast checker online: AA 4.5:1, AAA 7:1, large text 3:1
WCAG contrast rules look like a single number, but the threshold depends on text size and you cannot pass with a casual gradient. Two ratios cover most of the law.
AA, AAA, and what each means
WCAG 2.1 AA is the level most jurisdictions require by law. It asks for a contrast ratio of 4.5:1 between text and its background for normal-size text, and 3:1 for large text. Large text means 18 point or larger, or 14 point or larger if the text is bold. In CSS pixels that is roughly 24 px or 18.66 px bold.
WCAG AAA is the stricter tier, often required for government and accessibility-first projects. It pushes the ratio to 7:1 for normal text and 4.5:1 for large text. AAA is harder to design around because most brand palettes do not survive a 7:1 cut against a white background.
Non-text UI components and graphical elements need 3:1 against adjacent colors at any size. That covers form borders, focus rings, icon strokes, and chart elements.
The formula in plain words
The contrast ratio is computed from relative luminance. Take the linear RGB of each color, weight the channels (red 0.2126, green 0.7152, blue 0.0722, after sRGB linearization), and you get a luminance number between 0 and 1. The ratio is (L1 + 0.05) / (L2 + 0.05) where L1 is the lighter color and L2 is the darker one.
The 0.05 offset is what makes pitch black on white land at 21:1 instead of infinity, and it is also what makes near-black against black still produce a measurable ratio. The cap is 21:1, the floor is 1:1.
You do not have to compute this by hand. Every modern accessibility tool exposes the function, and a browser-side checker is one paste away.
Common failures
The most frequent failure is light gray placeholder text on a white background. Designers reach for #999 or #aaa thinking it looks subtle. #999 on white is 2.85:1, well below AA. Use #767676 (4.54:1) or darker.
Second most common is brand color buttons on white. A pure orange or yellow brand can sit at 1.5:1 against white, fine for a logo but a fail for a button label. Either darken the foreground or swap to white text on a darker fill.
Third is text on photo backgrounds. Hero sections often place white type over a real photo with no overlay. The contrast varies pixel by pixel and parts of the headline fall below 4.5:1. The fix is a semi-transparent dark overlay or a text shadow, not a bigger font.
How to fix without redesigning
Three moves cover most cases. Darken the foreground until the ratio passes. A label that is now #444 instead of #777 keeps the layout identical and clears AA. Add a subtle drop shadow on text over images, which raises the effective contrast for the eye even if the formula does not score it.
Simplify gradients. If your background is a gradient, the contrast against the lightest stop is what counts. Swap to a solid color or shorten the gradient range so every pixel under text passes.
Test with a real checker, not a screenshot eye check. The eye is a bad meter, especially for blue and red, which luminance weights very differently from how they look.
Working example
javascript// WCAG 2.1 contrast ratio between two CSS hex colors
function luminance(hex) {
const c = hex.replace("#", "");
const [r, g, b] = [0, 2, 4].map(i => parseInt(c.slice(i, i + 2), 16) / 255);
const lin = v => v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
}
function contrastRatio(fg, bg) {
const L1 = luminance(fg);
const L2 = luminance(bg);
const [bright, dark] = L1 > L2 ? [L1, L2] : [L2, L1];
return (bright + 0.05) / (dark + 0.05);
}
console.log(contrastRatio("#767676", "#ffffff").toFixed(2)); // "4.54"
console.log(contrastRatio("#999999", "#ffffff").toFixed(2)); // "2.85" Just need the result?
When you are checking a palette before shipping a design, the WCAG contrast checker in aldeacode.com computes the ratio in real time as you tweak hex values, flags AA and AAA passes for both normal and large text, and runs entirely in your browser. No upload, no waiting, instant feedback.
Open WCAG Contrast Checker →Frequently asked questions
Does AA contrast apply to disabled form controls?
No, disabled controls are explicitly exempt under WCAG 2.1. They still benefit from 3:1 for clarity, but the spec does not require it. Focus rings on enabled controls do need to hit 3:1 against adjacent colors.
Is 14 point bold really considered large text?
Yes, that is the WCAG definition. 14 point bold or 18 point regular both qualify, which in CSS pixels is around 18.66 px bold or 24 px regular. The lower threshold of 3:1 only applies once you are clearly above that line.
Do I need to check every color combination on the page?
Every text-on-background pair, plus any non-text component that conveys information through color (form borders, focus rings, chart slices). Decorative graphics with no information value are exempt. Most pages reduce to under 10 distinct combinations once you list them.