Color Contrast Checker
Calculate the contrast ratio between text and background in real time using the WCAG 2.1 relative luminance formula, with AA/AAA pass or fail judgment for accessible interface design.
What color contrast is, and why it matters for readability
Color contrast ratio measures the difference in relative luminance between a foreground color (usually text) and its background. It is not a subjective impression of "how different two colors look"; it is a well-defined, repeatable number that ranges from 1:1 (identical) to 21:1 (pure black on pure white). Contrast matters because whether text can be read comfortably depends fundamentally on the luminance gap between the strokes and the background, not on the hue difference. Two people with different sensitivity, or two screens with different brightness, may disagree on whether a color scheme looks nice, but they can both agree on whether it is legible once the same formula is applied.
In web accessibility this standard is set by the W3C's WCAG (Web Content Accessibility Guidelines). WCAG makes "sufficient contrast between text and background" a hard success criterion (1.4.3 Contrast (Minimum) and 1.4.6 Contrast (Enhanced)). The point is not aesthetics: it is to let people with low vision, presbyopia, or color-vision differences, as well as anyone using a device in bright sunlight or on a low-resolution screen, read the content reliably. For a public-facing website, meeting AA is generally treated as the minimum acceptable bar; failing it means a portion of users is effectively locked out. That is also why many design systems run a dedicated contrast check before shipping.
Relative luminance: the basis of the calculation
The contrast calculation has two steps, and the core concept is "relative luminance" — how bright a color appears after perceptual weighting by the human eye. Note that this "brightness" is not the raw 0–255 value on screen; it is the value after gamma correction (the nonlinear sRGB encoding is converted back into something close to real light intensity).
For each channel, first normalize 0–255 to the range 0–1, call it c; if c ≤ 0.03928 the linear value is c ÷ 12.92, otherwise it is ((c + 0.055) ÷ 1.055) raised to the power 2.4. After obtaining the linear R, G, B, weight them by human-eye sensitivity:
Relative luminance formula: L = 0.2126 · R + 0.7152 · G + 0.0722 · B
The three weights sum to exactly 1. Green has the largest weight (0.7152) because the eye is most sensitive to green; blue has the smallest (0.0722) because the same light intensity looks darkest in blue. This also explains a common misconception: contrast depends only on brightness, not on whether a color is red or blue. Darkening or lightening a color changes contrast far more through its luminance than through its hue.
Given the relative luminance L1 (lighter) and L2 (darker) of two colors, the contrast ratio is:
Contrast formula: (L1 + 0.05) ÷ (L2 + 0.05)
The +0.05 in the denominator comes from the eye's "threshold luminance" against a fully black background (black is never absolute zero brightness), which keeps the darkest cases from producing division by zero or infinity. Always put the lighter color in the numerator and the darker in the denominator, or you will get a reciprocal below 1.
WCAG 2.1 contrast thresholds
The table below shows WCAG 2.1 requirements by content type. It separates "body text" from "large text / UI components" because they need different contrast levels (the reason follows in "Contrast and font size").
| Content type | AA (minimum) | AAA (enhanced) | Notes |
|---|---|---|---|
| Normal body text | ≥ 4.5:1 | ≥ 7:1 | Applies to most website body copy; AA is the widely accepted floor |
| Large text (≥18pt, or ≥14pt bold) | ≥ 3:1 | ≥ 4.5:1 | Relaxed threshold because the text is big |
| UI components and graphics (button borders, icons, input outlines, chart lines) | ≥ 3:1 | — | WCAG 2.1 does not set a higher AAA bar for UI components; graphics objects are advised at ≥ 4.5:1 |
How to use it: first decide whether the element you are checking is "body text" or "large text / UI component". If it is body text, target at least 4.5:1 (push to 7:1 for higher readability). If it is button text, an icon, or a link underline, reaching 3:1 already satisfies AA. Many teams set their internal standard stricter than WCAG — for example requiring 7:1 for all body text — which is a safer enhanced practice.
Real contrast of common color combinations
Numbers alone are hard to picture, so here are several combinations designers frequently hit. Notice the last two: #767676 and #777 differ by a single step, yet one just passes AA and the other just fails.
| Foreground | Background | Relative luminance L (fg) | Contrast | Verdict |
|---|---|---|---|---|
| #000000 (black) | #FFFFFF (white) | 0.0000 | 21:1 | Far above AAA, safest possible |
| #333333 (dark gray) | #FFFFFF | 0.0331 | ≈ 12.6:1 | AAA; the usual safe choice for body text |
| #595959 (mid gray) | #FFFFFF | 0.1000 | ≈ 7:1 | Exactly hits the AAA body-text bar |
| #767676 (light gray) | #FFFFFF | 0.1810 | ≈ 4.54:1 | Just clears AA 4.5:1 (borderline) |
| #777777 (light gray) | #FFFFFF | 0.1844 | ≈ 4.48:1 | Misses AA by a hair |
| #949494 (lighter gray) | #FFFFFF | 0.2960 | ≈ 3.03:1 | Only meets AA for large text / UI components |
How to use it: the pair worth memorizing is #767676 versus #777. Many design systems set default body gray to #767676, sitting at 4.54:1 and just clearing AA; the moment someone "lightens it one step" to #777, it drops to 4.48:1 and fails AA, even though the human eye can barely tell the difference. So never pick body gray by feel — pin it to the 4.5:1 formula. If you are sampling a color from the screen, use the Color Picker to read it as a hex value, then come back to verify.
Formula and worked examples
Let's walk through real numbers so you can check the tool's output.
Example 1 (black on white = 21:1): black L = 0, white L = 1. Contrast = (1 + 0.05) ÷ (0 + 0.05) = 1.05 ÷ 0.05 = 21:1. This is the theoretical maximum and the top of the contrast scale.
Example 2 (#595959 gray on white ≈ 7:1, AAA): #59 = 89, normalized c = 89 ÷ 255 ≈ 0.3490; since c > 0.03928, linear = ((0.3490 + 0.055) ÷ 1.055)^2.4 ≈ (0.3829)^2.4 ≈ 0.1000. All three channels equal, so L = 0.2126×0.1 + 0.7152×0.1 + 0.0722×0.1 = 0.1000. Contrast = (1 + 0.05) ÷ (0.1 + 0.05) = 1.05 ÷ 0.15 = 7:1, exactly the AAA body-text bar.
Example 3 (why 3:1 only fits large text): take #949494 on white, L ≈ 0.2960, contrast = 1.05 ÷ (0.2960 + 0.05) ≈ 1.05 ÷ 0.346 ≈ 3.03:1. This only satisfies AA for large text or UI components; used as small body text it blurs. The reason is in the next section. You can verify the (L1+0.05)/(L2+0.05) ratio arithmetic with the Percentage Calculator.
How to use this tool
- Pick a color or type a hex value for the foreground (text) and the background
- The tool computes the ratio in real time and shows AA/AAA results for each level
- A preview area renders sample text with your chosen colors
- If a level fails, adjust the colors until it passes
Frequently asked questions (color-contrast specific)
What is relative luminance, and how is it different from a raw color value? Relative luminance is the perceived "how bright" value after perceptual weighting and gamma correction, ranging from 0 (black) to 1 (white). It is not the raw 0–255 sRGB value: each channel must first be linearized with (c+0.055)/1.055 to the power 2.4, then weighted by 0.2126, 0.7152, 0.0722. The contrast formula uses only this luminance and ignores hue, so "dark red" and "dark blue" at the same luminance give the same contrast.
Should body text use 3:1 or 4.5:1, and how do I choose? It depends on the object. Normal small body text must be ≥ 4.5:1 (AA), and you can push to 7:1 (AAA) for higher readability. Only "large text" (≥18pt, or ≥14pt bold) and "UI components / graphics" (button borders, icons, input outlines) are allowed to relax to 3:1. Simple rule: small text you must read → 4.5:1; non-text shapes you only need to recognize → 3:1.
What is the relationship between contrast and font size? It is direct. The larger and bolder the text, the lower the luminance gap the eye can still resolve, so WCAG asks only 3:1 for large text; small body text has thin strokes that blur when the gap is too small, so it requires 4.5:1. In other words, the same color pair may pass as a big heading but fail as small body text — never assume a heading that "looks clear" is also fine for body copy.
Why do light gray texts (such as #777) so often fail? Because light gray is too close to white in luminance. As the examples show, #767676 on white is about 4.54:1 and only just clears AA, while one step darker at #777 it drops to 4.48:1 and fails. Designers often treat light gray as "soft and premium", but that softness comes precisely from a small luminance gap, which is the enemy of readability. When you need light text, go down to around #595959 (≈7:1) to be safe.
How should I interpret the ratio the tool gives? The larger the ratio the clearer the text: 1:1 means no difference and is unreadable, 21:1 is the top. Check against three bars: ≥7:1 is AAA body text, ≥4.5:1 is AA body text, ≥3:1 is only enough for large text and UI components. If it fails the target level, the tool shows a fail notice; deepen the text or lighten the background to fix it. For counting the words in the copy you are checking, pair this with the Word Counter.