WCAG Contrast Checker
The exact contrast ratio for any two colors, with AA and AAA pass/fail for normal text, large text and UI components.
Runs 100% in your browser•Nothing is uploaded to a server•Free forever
Text color
Background color
Result
Normal text at 16px — the size most body copy actually is.
Large text at 24px
Large text at 18.66px bold
UI component border—:1
How the contrast ratio is calculated
WCAG 2.1 defines contrast as (L1 + 0.05) / (L2 + 0.05), where L1 is the relative luminance of the lighter color and L2 that of the darker one. Relative luminance is not the average of the channels: each of R, G and B is divided by 255, linearised (c / 12.92 below the 0.03928 knee, ((c + 0.055) / 1.055) ^ 2.4 above it), then weighted 0.2126 R + 0.7152 G + 0.0722 B — green carries most of the luminance because the eye is most sensitive to it. Black comes out at 0, white at 1, and the two together give the maximum possible ratio of 21:1.
AA vs AAA, and what counts as large text
There are only three numbers to remember, and each one appears twice:
- 4.5:1 — AA for normal text (SC 1.4.3), and AAA for large text (SC 1.4.6).
- 7:1 — AAA for normal text.
- 3:1 — AA for large text, and AA for user-interface components and graphical objects (SC 1.4.11), which is what a focus ring, an input border or an icon has to clear.
"Large" is a size, not an opinion: at least 18pt, or 14pt bold — about 24px, or 18.66px bold, on the web. The preview above shows all three sizes at once so you can see which threshold your own type actually falls under.
#767676 is the famous one. It is the darkest neutral grey that still clears 4.5:1 on white, at 4.54:1 — one shade lighter, #777777, drops to 4.48:1 and fails. That is how little headroom a "close enough" grey has.
The lightness nudge
When a pair fails, the Nudge lightness until it passes button walks the text color's lightness in OKLCH — hue and chroma held fixed — in whichever direction reaches the target first, and reports the hex it landed on. OKLCH rather than HSL because OKLCH's lightness axis is perceptually uniform: darkening a blue in HSL visibly shifts it toward purple, while in OKLCH it stays the same blue, only darker. Every candidate is converted back to sRGB and re-measured before it is offered, so the ratio shown is the ratio of the hex shown — gamut clamping included. If no lightness of that hue can reach the target, the page says so instead of handing you a color that fails.
A translucent text color is composited onto the background before it is measured, because a ratio is only meaningful for the color the eye actually receives. Everything runs locally in your browser — nothing is uploaded. Need to convert a color rather than check it? The color converter shares this page's color maths.
More developer tools
- Color Converter (HEX / RGB / HSL / HSV)
- JSON Formatter
- Base64 Encode / Decode
- URL Encoder / Decoder
- Unix Timestamp Converter
- Regex Tester
- UUID Generator (v4 / v7)
- Hash Generator (MD5 / SHA / HMAC)
- JWT Decoder
- Password Generator
- JSON ⇄ CSV Converter
- HTML Entity Encoder / Decoder
- Cron Expression Explainer
- All tools on one page (home)