Contrast Checker

Check color contrast ratios for WCAG AA and AAA compliance.

Result
Contrast Ratio14.63:1
AA Normal Text (4.5:1)
Pass
AA Large Text (3:1)
Pass
AAA Normal Text (7:1)
Pass
AAA Large Text (4.5:1)
Pass

About This Tool

What this tool does

The Contrast Checker measures how readable one color is on top of another and tells you whether that pairing clears the WCAG accessibility thresholds for text. You pick a text color and a background color, and it returns a single contrast ratio (something like 14.63:1 or 4.5:1) along with four Pass or Fail badges, one for each of the four bars in the WCAG 2.x text-contrast rules. The page opens with a dark slate text color (#1e293b) on a white background as its starting example, which produces a 14.63:1 ratio and passes every level.

Who needs to use it

Anyone who is shipping text on a screen and wants to confirm it stays legible. The common audiences:

  • Designers sanity-checking a palette before handing it to engineering — especially when a brand color sits close to a neutral and you suspect it might fail AA.
  • Frontend developers auditing tokens (--text-secondary, --text-muted, placeholder color, disabled-state color) that tend to drift toward "too pale" over time.
  • Accessibility reviewers producing a written record that a pairing meets AA, which is the level most accessibility laws and procurement audits reference.
  • Anyone making a slide deck, dashboard, or marketing page who has had a stakeholder squint at the screen and ask "can you read that?" once too often.

How to use it

There are only two controls. Click the Text Color swatch to open your operating system's native color picker and choose the foreground (the color of the actual letters). Click the Background Color swatch and pick the color that sits directly behind those letters. The Result card recalculates instantly on every change — no submit button, no debounce.

The result card shows five lines. The top line is the contrast ratio itself, written in the standard X:1 form and rounded to two decimal places. Below it are four pass/fail badges:

  • AA Normal Text — needs 4.5:1. This is the bar most people are aiming for. It applies to ordinary body copy, captions, and labels.
  • AA Large Text — needs 3:1. Applies to text that is at least 18pt (about 24px) at regular weight, or at least 14pt (about 18.66px) at bold weight and above.
  • AAA Normal Text — needs 7:1. A stricter target. Useful for long-form reading content where you want extra legibility headroom; not legally required by most standards.
  • AAA Large Text — needs 4.5:1. The AAA equivalent for the larger-text size bucket.

Pick whichever badge corresponds to the size and weight of the text you're actually shipping. For everyday body copy, the one that matters is AA Normal Text (4.5:1).

How it works under the hood

The tool runs the standard WCAG 2.x contrast-ratio calculation in three steps, all in your browser as you change the inputs.

Step 1: hex to relative luminance. Each color is split into its red, green, and blue channels (each 0–255) and divided by 255 to land in the 0–1 range. Each channel is then linearized to undo the sRGB gamma curve: if the channel is at or below 0.03928, it is divided by 12.92; otherwise it is raised through ((channel + 0.055) / 1.055) ^ 2.4. Linearized channels are then combined as a weighted sum:

L = 0.2126 × R + 0.7152 × G + 0.0722 × B

Those weights reflect how human vision responds to each primary — green contributes the most, blue the least — which is why bright yellow looks luminous and pure blue looks dark even at full saturation.

Step 2: the ratio. Compute (L1 + 0.05) / (L2 + 0.05), where L1 is the luminance of the lighter color and L2 the darker. The + 0.05 term models a small amount of ambient screen reflection, and it neatly prevents division by zero when one color is pure black. The result is always at least 1:1 and at most 21:1.

Step 3: round and compare. The ratio is rounded to two decimal places and checked against the four thresholds (4.5, 3, 7, 4.5). Each comparison produces the corresponding Pass or Fail badge.

One footnote for the very precise: WCAG 2.1 quietly swapped the linearization cutoff constant from 0.03928 to 0.04045. The difference is negligible in real-world checks — almost no color pair lands in the sliver between those two values — and most contrast tools, this one included, still use the original 0.03928. If your audit requires the newer constant exactly, flag it and verify against a tool that exposes its source.

Worked example

Let's walk through the default. Text is #1e293b (a deep slate), background is #ffffff (white).

For the text color, the channels are 0x1e = 30, 0x29 = 41, 0x3b = 59. Divided by 255 those become roughly 0.118, 0.161, 0.231. All three are above 0.03928, so each is linearized with the power formula and the weighted sum lands at L ≈ 0.0226. White's luminance is 1.0 exactly. The ratio is (1.0 + 0.05) / (0.0226 + 0.05) ≈ 14.63, which the tool displays as 14.63:1. Every badge says Pass.

Now try #777777 on white — the classic "looks like a fine medium gray" that most people assume is safe. Its luminance is about 0.184, and the ratio comes out to 4.48:1. That's a Fail on AA Normal (it needs 4.5), a Pass on AA Large, a Fail on AAA Normal, and a Fail on AAA Large. The number is striking: 0.02 away from passing. Bumping the gray one shade darker, to #767676, just barely clears the 4.5 bar — which is why so many design systems pick that exact gray for muted text. Going the other direction, #959595 on white lands almost exactly at 3:1 — that's the floor for AA Large text.

Common pitfalls

  • "Large text" isn't what most people think. A 16px body paragraph is normal text, even if it is your heading-sized headline in a tiny modal. The 3:1 bar only applies once you cross 18pt regular (24px) or 14pt bold (about 18.66px). When in doubt, hold yourself to 4.5:1.
  • Transparent colors don't tell the truth. The pickers only produce solid hex colors, but lots of real text sits on a semi-transparent overlay (a rgba(0,0,0,0.6) scrim on top of a hero image, a --text-muted token defined as color-mix(...), or a glass-effect card). Contrast depends on the pixels a viewer actually sees, so flatten the semi-transparent color against whatever sits behind it first, then paste the resulting solid hex into the tool.
  • Photos and gradients behind text break the assumption. A contrast ratio is meaningful only for a single foreground against a single background. If your text crosses a gradient or sits on a photo, the worst-case pixel under the text is what matters — usually a brightish midtone — and you should check against that, not against an "average" color you eyeballed.
  • Placeholder text and disabled states are where most real audits find failures. Designers often style them as a light gray that looks appropriately faded but lands somewhere around 3:1 on white. AA requires 4.5:1 for placeholder text that conveys information. If you only check one set of tokens today, check those.
  • Hover, focus, and visited states each have their own foreground/background pair. Don't assume the resting state passing implies the hover state passes.
  • Brand colors are not exempt. A logo can use any color, but the moment you set body text in a brand orange on white, that pairing has to clear 4.5:1 like everything else. If the brand color won't pass, use it for icons or large display text where 3:1 applies, or pair it with a darker neutral for body copy.

What to do if the result looks wrong

The most common "this can't be right" moments:

  • "Two colors look identical to me but the ratio is 1.5:1, not 1:1." Trust the math. Human perception is unreliable for small lightness differences, especially in midtones. Open the colors in any other contrast checker — they will agree.
  • "My gray passes AA on one site and fails on another." Check the background. Designers tend to test on pure white, but a card sitting on #f8f9fa (a typical off-white "background-subtle") changes the contrast against the gray inside the card. Pure-white assumptions are a frequent source of "passes in Figma, fails in production" bugs.
  • "My hex code is shorter than six characters." The native color picker always returns a 6-digit hex, so if you typed a 3-character hex (#abc) into a tool elsewhere and got a different answer, that tool was expanding it to #aabbcc first. This tool does the equivalent under the hood because the input is locked to 6-digit.

When NOT to use it

  • Non-text UI elements with their own rule. The four badges shown here are for text. WCAG 1.4.11 ("non-text contrast") covers icons, form-control borders, focus indicators, and meaningful graphical objects — those need 3:1 against adjacent colors. You can still use the ratio in this tool for those checks; just read it against the 3:1 bar (the AA Large Text badge) instead of 4.5:1.
  • APCA / WCAG 3. A newer contrast model called APCA (Advanced Perceptual Contrast Algorithm) is being developed for WCAG 3 and produces different numbers (it scores on a roughly -108 to +106 lightness-contrast scale, not a ratio). APCA is more perceptually accurate, especially for dark mode and thin fonts, but it is not yet the legal or standards-compliance bar in most places. If you're chasing AA or AAA, use this tool. If your team has explicitly adopted APCA, use an APCA-specific tool.
  • Color-blindness checks. Passing 4.5:1 says nothing about whether your design works for someone with deuteranopia, protanopia, or tritanopia. Two colors with strong contrast can still be indistinguishable to a color-blind viewer (red text on a green button being the canonical example). For that, use a color-blindness simulator alongside the contrast check.
  • Print. WCAG contrast is defined for emissive screens with a small ambient-light assumption baked into the +0.05 term. Print contrast is a separate discipline.

Adjacent concepts worth knowing

The 1.4.11 non-text rule — 3:1 for UI components and graphical objects — is the other contrast rule that lands on real audits. Form-input borders, the line under an underlined link, the icon inside an icon-only button, and your focus ring all need 3:1 against whatever they sit on. Focus rings in particular are frequent failures: a 1px light-blue ring against a white background often fails, even when the button itself passes.

Large text bonus. The 3:1 bar exists because larger text strokes are easier to resolve at lower contrast — your eye doesn't need to work as hard on a 32px headline as on a 13px footnote. Use the bonus honestly: don't shrink a "large" headline once it has passed and assume it still passes.

Dark mode flips the math but not the bar. The ratio is symmetric — white on black gives the same 21:1 as black on white — but the colors that need attention are different. Mid-dark grays on a near-black background are the dark-mode equivalent of light grays on white, and they fail in the same way.

A pass is necessary, not sufficient. A green badge here confirms that your text-versus-background contrast meets a specific WCAG number. It does not confirm that your font is large enough, that your line height is comfortable, that your hit targets are reachable, that the page works at 200% zoom, or that a screen reader can parse it. Treat the result as one box checked on a longer list.

Privacy

Every calculation runs locally in your browser. The colors you pick are never sent to a server, and the page works offline once it has loaded.

The about text and FAQ on this page were drafted with AI assistance and reviewed by a member of the Coherence Daddy team before publishing. See our Content Policy for editorial standards.

Frequently Asked Questions

What contrast ratio do I actually need to pass?
For normal body text, 4.5:1 clears WCAG AA — the level most accessibility laws, procurement audits, and design-system reviews reference. 3:1 is enough for large text (18pt regular, or 14pt bold and heavier). AAA (7:1 normal, 4.5:1 large) is a stricter optional target. The tool shows all four results side by side so you can pick the bar that applies to you. If you only remember one number, remember 4.5:1.
Why does the ratio go from 1:1 up to 21:1?
1:1 means the two colors are identical and the contrast is zero. 21:1 is the absolute maximum, produced only by pure black (#000000) against pure white (#ffffff). The 21 isn't arbitrary — it falls out of the formula because white's relative luminance is 1.0 and black's is 0.0, and (1.0 + 0.05) / (0.0 + 0.05) = 21. Every other color pair lands somewhere in between.
What counts as "large text" for the 3:1 rule?
WCAG defines large text as at least 18 point regular weight (roughly 24px on a screen) or at least 14 point bold (roughly 18.66px). Anything smaller, or anything between regular and bold at typical body sizes, counts as normal text and needs to clear 4.5:1, not 3:1. When in doubt, hold yourself to 4.5:1.
Does this also cover icons, form borders, and focus rings?
The four badges in this tool are for text. Non-text UI elements (icons, input borders, button outlines, focus indicators, meaningful graphical objects) are covered by WCAG 1.4.11 and need 3:1 against the colors they sit next to. You can still use this tool to measure them — read your ratio against the 3:1 bar (the AA Large Text badge) instead of 4.5:1.
Can I check colors that use transparency or rgba?
Not directly. The pickers are native color swatches that only produce solid hex colors. Contrast depends on the actual pixels a viewer sees, so a semi-transparent color has to be flattened against whatever sits behind it first. Blend the semi-transparent color down to the solid hex it visually resolves to, then paste that hex into the tool. A common case: text at rgba(0, 0, 0, 0.6) over a white card flattens to roughly #666666 — paste that and check.
Is a Pass here a guarantee my design is accessible?
A pass confirms that your text-versus-background contrast meets that specific WCAG number, which is one piece of accessibility — not the whole picture. Font size and weight, contrast against busy background images or gradients, focus indicators, color-blind-safe palettes, keyboard navigation, screen-reader semantics, and zoom behavior are all separate concerns. Treat the result as necessary, not sufficient.
Why does my favorite brand color fail AA?
Mid-saturation colors against white are hard. A vivid brand red, orange, or yellow often lands somewhere between 2:1 and 4:1 against white — fine for logos, large display text, and decorative shapes, but failing for body copy. Either darken the brand color when it's used as text, reserve the brand color for headings large enough to qualify under the 3:1 rule, or set body copy in a darker neutral and use the brand color for accents only.
Is this WCAG 2 or WCAG 3 / APCA?
WCAG 2 (2.0/2.1/2.2 — the formula is the same across those versions). WCAG 3 is in draft and proposes a different model called APCA that produces different numbers and is more perceptually accurate, especially for dark mode and thin fonts. APCA is not yet the legal or standards bar in most places, so for AA or AAA compliance use this tool. If your team has explicitly adopted APCA, use a tool built for it.
Does the tool send my colors anywhere?
No. The calculation runs entirely in your browser in JavaScript. Nothing about the colors you pick leaves your device, and the page keeps working offline once it has loaded.