Color contrast ratio formula
This color contrast checker uses the formula from WCAG 2.x. First, each color is converted to its relative luminance, a number from 0 (black) to 1 (white) that reflects how bright the color looks to the human eye. Then the two luminances are compared:
contrast = (L_lighter + 0.05) ÷ (L_darker + 0.05)
Relative luminance comes from the red, green and blue channels. Each channel is divided by 255, linearized to undo the sRGB gamma curve, then weighted, because the eye is far more sensitive to green than to blue:
c = channel ÷ 255
linear = c <= 0.04045 ? c ÷ 12.92 : ((c + 0.055) ÷ 1.055)^2.4
L = 0.2126 × R + 0.7152 × G + 0.0722 × B
The WCAG text quotes 0.03928 as the linearization threshold, while the sRGB standard uses 0.04045. No 8-bit channel value falls between the two, so both give identical results. The 0.05 offset accounts for ambient light reflecting off the screen, and it is why the ratio tops out at 21:1 for black on white.
Worked example
Gray #767676 on white. Each channel is 118, so c = 118 ÷ 255 = 0.4627. That is above 0.04045, so linear = ((0.4627 + 0.055) ÷ 1.055)^2.4 = 0.1812. All three channels are equal, so L = 0.1812. White has L = 1. The ratio is (1 + 0.05) ÷ (0.1812 + 0.05) = 4.54:1, which passes AA for normal text.
WCAG contrast reference table
Ratios for common colors on a white background, calculated with the formula above.
| Text | Background | Ratio | Notes |
|---|---|---|---|
#000000 | #ffffff | 21:1 | Maximum possible contrast |
#1a1a1a | #ffffff | 17.40:1 | Passes everything |
#595959 | #ffffff | 7.00:1 | Lightest gray that passes AAA normal text |
#767676 | #ffffff | 4.54:1 | Lightest gray that passes AA normal text |
#777777 | #ffffff | 4.47:1 | Fails AA normal text, passes large text |
#949494 | #ffffff | 3.03:1 | Large text and UI components only |
#ff0000 | #ffffff | 3.99:1 | Pure red fails AA for body text |
#0000ff | #ffffff | 8.59:1 | Pure blue passes AAA |
What the WCAG levels mean
- AA, normal text (4.5:1): the level most laws and accessibility policies point to. Body copy, labels, links and button text should meet it.
- AA, large text (3:1): large text is at least 24px regular or about 18.66px bold. Bigger letterforms are easier to read, so the bar is lower.
- AAA (7:1 and 4.5:1): the enhanced level. It is hard to meet for every brand color, but worth aiming for in long-form reading content.
- Non-text contrast (3:1): WCAG 1.4.11 asks that input borders, focus indicators, icons and chart elements needed to understand the content have at least 3:1 against what sits next to them.
The W3C explains the reasoning in Understanding Success Criterion 1.4.3: Contrast (Minimum), including which text is exempt, such as logos and purely decorative text.
Common contrast mistakes
- Rounding up. 4.47:1 is not 4.5:1. The thresholds are hard minimums.
- Checking only the default state. Hover, focus, visited and error states need to pass too, and so does text placed over images or gradients. Check the lightest area of the background behind the text.
- Trusting light gray placeholders. Many design kits ship placeholder and helper text that fails AA.
- Forgetting transparency. A semi-transparent color has a different effective value on every background. Work out the solid color it produces, then check that.
- Treating px and pt as the same. WCAG defines large text as 18pt, which is 24px in CSS.
How to fix a color pair that fails
You rarely need to abandon a brand color. Usually one of these small changes is enough:
- Darken the text or lighten the background in small steps and recheck. Moving a mid-gray from #777777 to #767676 is enough to cross 4.5:1 on white.
- Make the text large. If a color passes 3:1 but not 4.5:1, it can still be used for headings of 24px and up, or 18.66px bold.
- Keep the brand color for non-text elements, such as icons, borders and backgrounds of large areas, and use a darker shade of the same hue for text and links.
- Add a solid backing or a dark overlay behind text that sits on a photo, so the contrast no longer depends on the image.
Need the RGB values of a hex code first? Use the HEX to RGB converter. If you are sizing type to qualify as large text, the px to rem converter turns 24px into 1.5rem.
Frequently asked questions
What contrast ratio does WCAG AA require?
WCAG 2.x Level AA requires at least 4.5:1 for normal text and 3:1 for large text. Large text means at least 18pt (24px) regular or 14pt (about 18.66px) bold.
Is #767676 on white accessible?
Yes, just. #767676 on #ffffff has a ratio of about 4.54:1, which passes AA for normal text. One step lighter, #777777, drops to about 4.48:1 and fails.
Does the contrast ratio change if I swap text and background?
No. The formula always puts the lighter color on top of the fraction, so dark text on a light background and light text on a dark background give the same ratio. Swapping only changes how the design looks.
Do placeholder text and disabled buttons need to meet contrast?
Placeholder text is still text, so treat it like any other text. WCAG exempts inactive (disabled) user interface components from the contrast requirements, though making them readable is still kind to users.
Can I round 4.47:1 up to 4.5:1?
No. The thresholds are minimums, so a ratio of 4.47:1 fails AA for normal text. This checker truncates the displayed value rather than rounding it up, and the pass or fail result uses the unrounded ratio.
Does WCAG 2 contrast work for dark mode?
The same formula applies to any pair of colors, so you can and should check your dark theme too. Light text on very dark backgrounds can feel harsher than the ratio suggests, so test with real content.