Normal text AA 4.5:1
Change the text
#205EE6 4.52:1
Or change the background
#E8F2FF 4.57:1
WCAG 2.2 color contrast
Put in a text color and a background color: you get the ratio and a plain verdict for normal text, large text and interface parts. Below it, what WCAG 2.2 asks for, the nearest colors that pass, six ways to measure contrast, the pair through color blindness, and a matrix for a whole palette.
The quick check needs JavaScript. Without it, this is the example pair.
Not a color yet.
Not a color yet.
Hex, rgb(), hsl() or a CSS color name. A see-through color is blended first.
See-through text, blended onto the background:
See-through background, measured over white:
4.23:1 contrast ratio
Passes for large text and UI parts only. Normal text fails AA.
The rules
Three success criteria set the numbers. Level AA is the one laws and contracts usually cite; AAA is stricter, and W3C does not recommend requiring it across a whole site.
| What | Level AA | Level AAA | Success criterion |
|---|---|---|---|
| Normal textAnything below the large-text size | 4.5:1 | 7:1 | 1.4.3 Contrast (Minimum) 1.4.6 Contrast (Enhanced) |
| Large textAt least 24 px, or 18.66 px when bold | 3:1 | 4.5:1 | 1.4.3 Contrast (Minimum) 1.4.6 Contrast (Enhanced) |
| UI components and graphicsControl borders and states, focus indicators, the parts of a chart needed to read it | 3:1 | No higher level | 1.4.11 Non-text Contrast |
| Focus indicatorAt least a 2 px perimeter, changed between focused and unfocused | Covered by 1.4.11 | 3:1 | 2.4.13 Focus Appearance |
WCAG defines large text as 18 point, or 14 point bold. At 1 pt = 1.333 CSS px, that is 24 px regular or about 18.66 px bold. A light-weight heading at 20 px is normal text, whatever it is called.
Sources: Understanding 1.4.3, Understanding 1.4.11, Understanding 2.4.13 (W3C).
Fix
The nearest colors that reach each target for the pair in the quick check. Each keeps its hue and chroma in OKLCH and changes only lightness, so a blue stays the same blue, a little darker or lighter.
Change the text
#205EE6 4.52:1
Or change the background
#E8F2FF 4.57:1
Change the text
#003CC3 7.07:1
Or change the background
No lightness of this background's hue gets there against this text.
Change the text
Already passes. Nothing to change.
Or change the background
Already passes. Nothing to change.
The walk moves lightness in steps of 0.005 and stops at the first step that passes, so a fix lands just over its target. When the text cannot get there at its hue, moving the background, or both, may; black or white always reach further, at the cost of the color itself. How to make a brand color accessible
Lightness
The text color at every lightness of its own hue, each measured on the background in the quick check. The bands show where it reaches each target, and the marker shows where it is now.
Lightness is OKLCH L, the first number in oklch(). Hue is kept and chroma is trimmed only where sRGB cannot show it, so every color on the strip is one you could use. A background in the middle of the range can leave two bands: one darker, one lighter.
The maths
WCAG compares the relative luminance of the two colors: how much light each gives off, from 0 for black to 1 for white.
The ratio runs from 1:1, the same color twice, to 21:1, black on white.
The definition in WCAG 2.2| Step | Text #2563EB | Background #DBEAFE |
|---|---|---|
| Channels, 0–255 | 37, 99, 235 | 219, 234, 254 |
| Divided by 255 | 0.1451, 0.3882, 0.9216 | 0.8588, 0.9176, 0.9961 |
| sRGB curve undone | 0.0185, 0.1248, 0.8308 | 0.7084, 0.8228, 0.9911 |
| Relative luminance L | 0.1532 | 0.8106 |
(0.8106 + 0.05) / (0.1532 + 0.05) = 4.2363
Shown to four decimal places; the division uses full precision. Change the pair in the quick check and this working follows it.
WCAG says the ratio is not rounded: 4.499:1 does not meet 4.5:1. A tool that rounds can turn a fail into what looks like a pass.
So every ratio on this site is cut to two decimals, never rounded up.
Until May 2021 WCAG printed 0.03928 where it now prints 0.04045, a figure taken from an older version of the sRGB specification. No 8-bit channel value falls between the two, so every hex color gets the same answer either way.
Models
The WCAG 2 ratio is the one audits and laws use. Design systems, display standards and color science measure the same pair in other ways, and they do not always agree. Every card follows the pair in the quick check.
4.23:1
Large text and UI parts only
The relative luminance of the lighter color over the darker, each plus 0.05 for screen glare.
(L1 + 0.05) / (L2 + 0.05)
Lc +61
Content text
Perceptual contrast that knows which color is the text: positive for dark text on light, negative for light on dark.
Lc, APCA-W3 0.0.98G-4g
0.68
Meets the 0.5 minimum
Michelson contrast of the two luminances, with no allowance for glare.
(L1 − L2) / (L1 + L2)
ΔL* 46.0
A gap of 40 to 50
The gap in CIELAB lightness, from 0 for black to 100 for white. Material Design's HCT color space calls it tone.
|L*₁ − L*₂|
Measured exactly, a gap of 40 never falls below 3.16:1, but a gap of 50 can land at 4.48:1, just under 4.5:1. Use the gap to plan, then measure the ratio.
ΔE00 38.7
Distinct
How different the two colors look overall: lightness, chroma and hue together.
ΔE00 (CIE 2001)
−0.76
Dark text on a light background
The change in luminance from the background to the text, as a share of the background, with the same 0.05 for glare.
(Lt − Lb) / (Lb + 0.05)
Color vision
Each row simulates a full deficiency (Machado, 2009). Contrast barely moves, because the simulations keep lightness; what shrinks is the difference in hue.
| Vision | Seen as | WCAG 2 | APCA | ΔE00 |
|---|---|---|---|---|
| Typical color vision | #2563EB / #DBEAFE | 4.23:1 | Lc +61 | 38.7 |
| Protanopia | #0076F0 / #E3EAFF | 3.60:1 | Lc +56 | 36.8 |
| Deuteranopia | #0064E8 / #E0E7FE | 4.27:1 | Lc +61 | 40.7 |
| Tritanopia | #00869D / #D3EEF0 | 3.52:1 | Lc +55 | 33.4 |
| Achromatopsia | #6D6D6D / #E8E8E8 | 4.22:1 | Lc +62 | 35.9 |
Red #DC2626 and green #16A34A look nothing alike to most people, yet as text on each other they reach only 1.46:1. Their difference is all hue, and with deuteranopia it nearly vanishes. ΔE00 with typical color vision: 72.4; with deuteranopia: 7.9.
So contrast is what keeps text readable for everyone, and a status shown only in red or green needs a word, an icon or a pattern as well.
Color blindness, type by type Color blindness simulator 1.4.1 Use of Color
Hard cases
The formula takes two flat colors. Real interfaces put text on photos, gradients and see-through layers, and change colors on hover, focus and in dark mode. Here is what to measure in each case.
A photo has thousands of background colors, and the text has to clear the worst one behind it: the lightest, for light text. A scrim makes that worst case known.
A darker pixel only adds contrast, so at 60% white text passes anywhere on the photo. Without a scrim, sample the lightest and darkest pixels behind the text with the image picker and check both. An automated scan samples one background color, so treat its verdict on a photo as a starting point.
Check the weakest stretch behind the text, not the two ends. Dark text #111827 on a pink-to-blue gradient passes at both ends and fails in the middle.
background: linear-gradient(in oklab 90deg, #EC4899, #3B82F6);
Hex colors in a gradient blend in gamma-encoded sRGB unless you name another space, which dims the middle between two hues; we checked that Chromium paints it so. The Gradient Library tool checks white and black text at 20 points across a gradient.
Open the Gradient Library tool Color gradients and interpolation
Blend first, then measure. A see-through color is painted as a mix of itself and what is underneath, channel by channel: alpha × color + (1 − alpha) × background.
Browsers keep alpha in steps of 1/255, so a blended channel can differ by one from a hand calculation. The quick check blends for you: type a color with an alpha channel.
Every state is its own pair, and each one that carries text has to pass. Hover is where links usually slip.
Disabled controls are exempt; a control that still works has to pass in every state. To check every state against every surface at once, put the set into the Accessibility Lab tool.
A focus ring is a UI part: it needs 3:1 against the colors next to it. Pale rings on white are the usual miss.
At AAA, Focus Appearance also sets a minimum size and a 3:1 change between focused and unfocused. Focus Not Obscured is about sticky headers hiding the focus, not about color.
2.4.7 Focus Visible 2.4.13 Focus Appearance 2.4.11 Focus Not Obscured (Minimum)
A dark theme is a second set of pairs, and each one needs measuring on its own surfaces. An accent that passes on white often fails on a dark gray.
Pick each dark-theme accent from a lighter step of its scale and measure it on the actual surface, not on black.
Dark mode and adaptive color A dark UI theme, every pair measured
WCAG 2 and APCA
APCA, the Accessible Perceptual Contrast Algorithm, weighs which color is the text and how large and heavy the type is. It was developed as a candidate method for WCAG 3.
Both numbers for the pair in the quick check.
The WCAG 2 ratio is symmetrical: swap text and background and the number does not change. APCA is not: dark text on a light ground and light text on a dark ground score differently, and the sign of Lc says which is which.
| Text | WCAG 2.2 ratio | APCA |
|---|---|---|
| White | 3.67:1 fails AA | Lc −69 |
| Black | 5.70:1 passes AA | Lc +40 |
WCAG 2 ranks black text higher on this blue; APCA ranks white higher. Where they disagree, the WCAG 2 result is the one audits and laws use.
Type
WCAG 2 sorts text into two sizes. APCA asks for more contrast the smaller and lighter the type.
Set a size and a weight for the pair in the quick check.
Large text in WCAG 2.2 is at least 24 px, or 18.66 px bold. APCA's bronze level defines only weights 400 and 700, so other weights count as the nearer of the two; this site holds weights under 400 one level stricter.
Palette
Put in up to ten colors, such as your tokens, brand colors or a theme, and see each one as text on each of the others. Measure with the WCAG 2 ratio or with APCA.
Hex, rgb(), hsl() or names, separated by spaces, commas or new lines.
Not read as colors:
| #111827 | #FFFFFF | #2563EB | #DBEAFE | #F59E0B | #DC2626 | |
|---|---|---|---|---|---|---|
| #111827 | Same color | 17.73:1Passes | 3.43:1Fails | 14.54:1Passes | 8.26:1Passes | 3.67:1Fails |
| #FFFFFF | 17.73:1Passes | Same color | 5.16:1Passes | 1.22:1Fails | 2.14:1Fails | 4.82:1Passes |
| #2563EB | 3.43:1Fails | 5.16:1Passes | Same color | 4.23:1Fails | 2.40:1Fails | 1.07:1Fails |
| #DBEAFE | 14.54:1Passes | 1.22:1Fails | 4.23:1Fails | Same color | 1.76:1Fails | 3.95:1Fails |
| #F59E0B | 8.26:1Passes | 2.14:1Fails | 2.40:1Fails | 1.76:1Fails | Same color | 2.24:1Fails |
| #DC2626 | 3.67:1Fails | 4.82:1Passes | 1.07:1Fails | 3.95:1Fails | 2.24:1Fails | Same color |
APCA scores are signed: positive for dark text on a light background, negative for light on dark; the target applies to the size of the number. A see-through color is measured over white.
Where next
From one pair to a whole page, a palette and a working pattern.
Further reading: Accessible color design and WCAG contrast, Color in data visualization, every WCAG criterion.
Method
Every number here comes from the site's color engine, the same one behind the contrast checker, and an automated test recomputes each of them, so a figure on this page cannot drift from the code.
The page is checked with axe-core and driven by keyboard in Chromium, in light and dark themes, on desktop and phone widths. It has not been tested with a screen reader.
A ratio checks a success criterion; it is not a full conformance review, and it is not legal advice.
Found a wrong number? Tell us.