Developers

How to Calculate Color Contrast Ratio (WCAG AA/AAA)

6 min read

Color contrast ratio measures how much a text color stands out from its background, expressed as a number from 1:1 (identical colors) to 21:1 (pure black on pure white). WCAG 2.1 sets minimum ratios for text to be considered readable: 4.5:1 for normal text at the AA level, the bar most accessibility audits and legal requirements use.

The formula

The ratio comes from each color’s relative luminance, not from how a color “looks” on screen. Four steps turn a hex code into a luminance value:

  1. Split the hex code into R, G, B and divide each by 255, so every channel is a value between 0 and 1.
  2. Linearize each channel. Screens don’t map color values to brightness in a straight line, so each channel gets gamma-corrected: if the value is ≤ 0.03928, divide it by 12.92; otherwise apply ((value + 0.055) / 1.055) ^ 2.4.
  3. Weight and sum the channels into relative luminance: L = 0.2126 × R + 0.7152 × G + 0.0722 × B. Green gets the heaviest weight because human eyes are most sensitive to it; blue gets the least.
  4. Divide the lighter luminance by the darker one, both plus 0.05: (L_lighter + 0.05) / (L_darker + 0.05).

That last + 0.05 matters: it stops the ratio from spiking toward infinity when one of the colors is near-black, and it’s why pure black on pure white caps out at exactly 21:1 instead of some much larger number.

Worked example: #767676 on white

This gray-on-white pair appears throughout WCAG documentation because it sits right on a threshold, which makes it a useful case to walk through by hand.

Step 1. #767676 in RGB is 118, 118, 118. Dividing by 255 gives 0.4627 for each channel.

Step 2. 0.4627 is above 0.03928, so linearize with the gamma formula: ((0.4627 + 0.055) / 1.055) ^ 2.4 = 0.1810. All three channels are equal here, so this value applies to R, G and B alike.

Step 3. Luminance: L = 0.2126 × 0.1810 + 0.7152 × 0.1810 + 0.0722 × 0.1810 = 0.1810. White’s luminance is 1.0 (every channel linearizes to exactly 1).

Step 4. Ratio: (1.0 + 0.05) / (0.1810 + 0.05) = 1.05 / 0.2310 = 4.545, rounded to 4.54:1.

That lands just above the 4.5:1 line for AA normal text, and just above the 4.5:1 line for AAA large text too, but well under the 7:1 AAA normal text requires. One hex value, three different verdicts depending on text size and which level you’re targeting.

How common color pairs actually fare

PairRatioAA Normal (4.5:1)AAA Normal (7:1)AA Large (3:1)AAA Large (4.5:1)
#AAAAAA on #FFFFFF2.32:1FailFailFailFail
#767676 on #FFFFFF4.54:1PassFailPassPass
#2563EB on #FFFFFF5.17:1PassFailPassPass
#333333 on #FFFFFF12.63:1PassPassPassPass

Two takeaways from this table. First, a mid-saturation blue like #2563EB (a common button and link color) clears AA for body text but fails AAA outright, so a site targeting AAA for links needs a darker shade. Second, the popular light-gray placeholder text around #AAAAAA fails every single threshold, including the 3:1 minimum for large text, which is why “subtle” gray-on-white UI copy is one of the most common accessibility audit findings.

Check your own colors

Enter any two hex values below to get the exact ratio and see which WCAG levels they pass, live, with no upload or server round trip.

The quick brown fox jumps over the lazy dog

The quick brown fox jumps over the lazy dog

Contrast ratio 21:1
Normal text
AA
AAA
Large text
AA
AAA
Color Contrast Checker
Free, no sign-up, works on any device.
Open the full tool

Common mistakes

Forgetting large text has a lower bar. WCAG defines “large text” as 18pt (24px) regular weight or 14pt (18.66px) bold and up. A 24px heading only needs 3:1, not 4.5:1, so a design system that applies the same contrast rule to every text size rejects headings that are already compliant.

Testing text contrast but not UI component contrast. WCAG 1.4.11 sets a separate 3:1 minimum for non-text elements like button borders, form field outlines, and icons that convey meaning on their own. A button with perfect 7:1 text contrast but a border that blends into the background can still fail an audit.

Checking contrast against the wrong background. Text sitting on a photo, a gradient, or a semi-transparent overlay doesn’t have one background color, it has many. The ratio only holds at the specific point you sampled; a gradient that’s light at the top and dark at the bottom needs the worst-case point checked, not the average.

Assuming brand colors are exempt. A logo wordmark is exempt from contrast requirements, but body copy and UI text set in a brand color is not. Many brand blues and brand reds that work fine as logo accents fail 4.5:1 when used as 16px paragraph text on white.

Frequently Asked Questions

What’s the difference between AA and AAA? AA is the standard most legal accessibility requirements (ADA in the US, EN 301 549 in the EU) reference, and it’s what most audits check against. AAA is stricter and mainly intended for content aimed specifically at users with low vision; WCAG itself notes AAA isn’t achievable for all content types, so most organizations target AA across the board rather than AAA everywhere.

Does contrast ratio account for color blindness? No. Contrast ratio measures luminance (brightness), not hue, so it incidentally helps many forms of color blindness by not depending on distinguishing specific colors. But it doesn’t replace a color-blindness check: two colors can have excellent contrast and still be hard to tell apart for someone with red-green color blindness if they differ mainly in hue rather than lightness.

Why is pure black on white 21:1 and not some rounder number? Luminance for black is 0 and for white is 1. Plugging those into the ratio formula gives (1 + 0.05) / (0 + 0.05) = 1.05 / 0.05 = 21. It’s exactly 21:1 because of how the +0.05 constant was chosen, not a coincidence or a rounded figure.

Does a dark mode theme need separate contrast checks? Yes. Swapping a light background for a dark one doesn’t preserve the ratio: white text on your brand blue and brand blue text on near-black are two different luminance pairs with two different ratios, so each theme needs its own pass through the checker rather than assuming the light-mode pairing’s result still applies.

AccessibilityWCAGCSSColor
Color Contrast Checker
Now try it yourself with the full tool.
Try it now