Color Contrast Checker
Check whether a text color and a background color meet WCAG 2.x contrast requirements — pick or type two colors and see the exact ratio, pass/fail badges for every WCAG level, and a live preview of how the pair actually looks.
- AA · Normal text (4.5:1)
- AA · Large text (3:1)
- AAA · Normal text (7:1)
- AAA · Large text (4.5:1)
- UI components & graphics (3:1)
Live preview
Normal text (16px) — the quick brown fox jumps over the lazy dog.
Large text, 24px regular
Large text, 18.66px bold
Everything above runs locally in your browser — no color values are sent to a server.
How to use the Color Contrast Checker
- Pick or type the text color using the swatch or hex field under "Text color."
- Pick or type the background color the same way under "Background color."
- Read the big contrast ratio and the five pass/fail badges underneath — each badge is a different WCAG requirement, explained in the table below.
- Check the live preview to see normal text, large text, a button and an input border rendered in the colors you chose.
- If "AA · Normal text" fails, a suggestion box offers the closest passing shade of your text color (same hue) — click "Use this color" to apply it.
- Use "Swap" to test the pair in reverse, or "Reset" for the starting colors.
How the contrast ratio is calculated
The checker uses the formula from WCAG 2.x Success Criterion 1.4.3 (Contrast (Minimum)) and 1.4.11 (Non-text Contrast). Each color's three 8-bit channels (0–255) are converted to the 0–1 range and "linearized" to undo sRGB gamma encoding:
csrgb = channel ÷ 255
If csrgb ≤ 0.04045, the linear value is
csrgb ÷ 12.92; otherwise it is
((csrgb + 0.055) ÷ 1.055)2.4. Those linear red, green
and blue values are then combined into a single relative luminance using weights that match
how sensitive human vision is to each channel:
L = 0.2126 × R + 0.7152 × G + 0.0722 × B
Finally, the contrast ratio between the lighter color's luminance (L1) and the darker color's luminance (L2) is:
ratio = (L1 + 0.05) ÷ (L2 + 0.05)
An older printing of the WCAG 2.0 text used 0.03928 instead of 0.04045 for that threshold; the difference changes luminance by a tiny fraction of a percent and never flips a real pass/fail result, so this tool uses the current 0.04045 value. The ratio ranges from 1:1 (identical colors) to 21:1 (black on white) and depends only on lightness, not hue — which is why two very different-looking colors can still fail if their luminance is too close.
Examples
Black text on a white background
#000000 on #ffffff has luminance 0 and 1, so the ratio is
(1 + 0.05) ÷ (0 + 0.05) = 21.00:1 — the maximum possible contrast,
passing every level in the table below.
Two nearly identical greys
#777777 on white comes out to 4.48:1, just under the 4.5:1
AA threshold for normal text, so it fails. Darkening it by a single hex step, to
#767676, raises the ratio to 4.54:1, which passes. This
one-digit difference is the actual reason several well-known style guides specify
#767676 rather than #777777 for secondary grey body text.
A brand blue
This site's own link color, #2952cc, on a white background computes to
6.62:1. That clears AA for both normal and large text and clears AAA for
large text (4.5:1), but falls short of AAA for normal text (7:1).
WCAG contrast levels at a glance
| Success criterion | Applies to | Minimum ratio |
|---|---|---|
| 1.4.3 — Contrast (Minimum), Level AA | Normal text | 4.5:1 |
| 1.4.3 — Contrast (Minimum), Level AA | Large text | 3:1 |
| 1.4.6 — Contrast (Enhanced), Level AAA | Normal text | 7:1 |
| 1.4.6 — Contrast (Enhanced), Level AAA | Large text | 4.5:1 |
| 1.4.11 — Non-text Contrast, Level AA | UI components & graphical objects | 3:1 |
What counts as "large" text
WCAG defines large text as at least 18pt (24px) regular weight, or at least 14pt (about 18.66px) bold weight, at standard browser scaling. Large text gets a lower minimum ratio because thicker, wider strokes stay legible at lower contrast than fine body text.
What's exempt from the contrast requirement
- Logotypes. Text inside a logo or brand name has no minimum contrast requirement under Success Criterion 1.4.3.
- Inactive or disabled controls. A greyed-out, disabled button or field is exempt, since it isn't available for the user to act on.
- Pure decoration. Text with no informational value, such as a faint watermark, or text that isn't visible to anyone.
- Incidental text in a photo. Text inside a picture that has other significant visual content is exempt; a heading rendered as an image of text is not.
A note on WCAG 3 and APCA
The next generation of the guidelines, WCAG 3, proposes a new contrast math called APCA (Accessible Perceptual Contrast Algorithm) that accounts for font weight, size and perceptual brightness more accurately than the formula above. As of today WCAG 3 is a W3C Working Draft, not a finished Recommendation, and APCA has no ratified pass/fail thresholds you can cite for compliance. Accessibility audits, legal requirements and AdSense-adjacent checks still test against WCAG 2.x, which is what this tool implements.
Practical tips for designers
- Don't pair a light grey with a slightly darker grey for body text — check against the actual page background, not a neighboring grey element.
- Check hover, focus and visited link states separately; a link that passes at rest often gets a lighter hover tint that quietly drops below 4.5:1.
- Text over a photo needs a solid box, gradient or scrim behind it — test against the busiest, most contrasting patch of the image, not its average color.
- Pure black on pure white (21:1) is not required. Many designers soften body text to something like #14161c, trading a little contrast margin for less eye strain.
Frequently asked questions
What is a good contrast ratio for body text?
Aim for at least 4.5:1 (WCAG AA, Success Criterion 1.4.3) for any normal-sized body text. Reaching 7:1 (AAA) is better for users with low vision, but AA is the level most accessibility audits actually require.
Does this checker work for gradients or photos?
No — it compares two flat colors. For text over a gradient or photo, test against the least-favorable point behind the text: the brightest patch if the text is dark, or the darkest patch if the text is light.
Why does #777777 fail but #767676 pass?
Relative luminance isn't linear with the hex value, so two visually indistinguishable greys can land on opposite sides of a threshold. #777777 on white computes to 4.48:1 (just under 4.5), while #767676 computes to 4.54:1 (just over it) — a well-known edge case in the accessibility community.
Is passing the contrast ratio the same as supporting color blindness?
No. Contrast ratio only measures lightness difference, not whether two colors are distinguishable to someone with a color vision deficiency. A red and a green with matching luminance can pass yet look identical to a colorblind user — never rely on color alone to convey information (Success Criterion 1.4.1).
Does my color data get sent anywhere?
No. Parsing and calculation happen locally in your browser; nothing is uploaded to a server.
Can I use this for buttons and icons, not just text?
Yes. Success Criterion 1.4.11 applies the same 3:1 minimum to the visible boundaries of UI components — borders, outlines, toggle states — and to meaningful graphical objects like icons or chart lines. Enter the component's own color as "Text color" and whatever it sits on as "Background color."