Checking Contrast for Large Text and Headings

Pick any foreground and background pair, see live WCAG 2.1 AA and AAA results for normal text, large text, and UI components, and fix failing pairs in one click.

ZERO UPLOAD · ALL LOCAL
  1. Type a foreground and a background color in any supported format (hex, rgb, hsl, hsv, oklch, or a CSS color name), or click either swatch to open the visual picker.
  2. Read the large ratio on the left and the per-tier badges in the preview: normal text, large text, and UI components each check against their own AA and AAA thresholds.
  3. When a row fails, click Fix text or Fix background to apply the closest color that passes without changing the hue. The button only appears when a passing fix exists.
  4. Use the toggle above the preview to view your exact pair through protanopia, deuteranopia, or tritanopia simulation. Ratios and badges keep reporting the true colors.
  5. Click Swap to flip foreground and background, or Share to copy a link that restores both colors for anyone who opens it.

Worked examples for this use case

A muted slate heading color that passes the tool's Large Text row but fails its Normal Text row

Before
Foreground #808a9c, background #ffffff
After
The Large Text (24px Bold) row clears AA at roughly 3.5:1, while the Normal Text (16px) row fails, since both rows render side by side for the same pair and only the large-text threshold is low enough to pass here.

A darker gray that clears both rows, not just the large-text one

Before
Foreground #6b7280, background #ffffff
After
This pair clears the Normal Text (16px) row at AA as well as the Large Text (24px Bold) row, so it works as a heading or as body copy without needing a separate check for either.
Unrecognized color format
Unrecognized color format

Contrast Ratio

Colorblind Simulation

Button Text Samples

Normal Text (16px)

Body copy at 16 pixels carries most of what your visitors actually read, and it needs 4.5:1 to pass AA.

Large Text (24px Bold)

Large text passes AA at 3:1

Buttons

Continue Cancel

Checking Large Text and Heading Contrast Against the Lower WCAG Thresholds

A heading styled at 32 pixels can pass WCAG at a contrast ratio that would fail outright as body copy, and that gap trips up more design reviews than almost any other single rule in the guideline. WCAG defines large text as at least 18 point, which works out to 24 CSS pixels at regular weight, or roughly 14 point bold, close to 18.7 pixels, and grants that category a lower bar: 3:1 for AA instead of the 4.5:1 normal text needs, and 4.5:1 for AAA instead of 7:1. Knowing exactly where that size threshold sits, and checking a heading color against the right tier rather than the stricter one meant for paragraphs, is the difference between rejecting a perfectly compliant color and shipping it.

Finding the exact pixel size where the lower threshold kicks in

The 18-point and 14-point-bold definitions in the WCAG spec sound abstract until you convert them into the CSS pixel values a browser actually renders, which is where most of the confusion around this rule comes from. Point sizes are a print-era unit, and most designers today think entirely in pixels, so the guideline's own wording needs a translation step before it becomes actionable.

Converting point sizes into the CSS pixels your stylesheet uses

Eighteen point works out to 24 CSS pixels at regular font weight, using the standard 1 point equals 1.333 pixels conversion, while 14 point bold lands close to 18.7 pixels.1 A 24px regular heading and an 18px bold label both qualify for the large-text thresholds, while a 20px regular subheading, a size many design systems use, falls just short and still needs to clear the stricter normal-text bar. That single missing pixel is easy to overlook in a spec review, yet it decides which of two very different ratio requirements actually applies.

That size boundary matters because thicker, taller letterforms genuinely stay legible at lower contrast than the same color pair would at body-text size,1 which is the entire reasoning behind WCAG granting large text a lower bar in the first place rather than treating every visible pixel identically. Treating a headline and a caption as if they carried the same legibility risk would waste real design freedom on the headline for no accessibility benefit.

Bold weight lowers the size threshold, not the contrast requirement

Bumping a heading to bold weight, font-weight: bold or the numeric 700,2 lowers the pixel size needed to qualify as large text, from 24px down to roughly 18.7px, but it does not change the ratio target itself once a piece of text does qualify. It's a useful lever for a compact UI label that needs large-text treatment without taking up as much vertical space as a full 24px line.

A bold 19px label and a regular 24px headline both need the same 3:1 for AA, so weight is a tool for hitting the large-text size threshold at a smaller footprint, not a separate lever on the ratio requirement. Confuse the two and you either reject a compliant bold label for a threshold it never needed to meet, or approve a regular-weight one that actually needed the stricter bar.

Checking a heading color against the right threshold

Type your heading's exact foreground and background into the fields above and read the Large Text row specifically, not the Normal Text row, since the two apply completely different thresholds to the same colors.3 Reading the wrong row is the single most common mistake in a heading-contrast review, and it goes in both directions, rejecting valid colors and approving invalid ones equally often.

A color that fails as body text can be a legitimate heading choice

A muted slate gray like #808a9c against a white background lands around 3.5:1, comfortably clearing the large-text AA bar while falling well short of the 4.5:1 normal text needs.4 Type that exact pair into the fields above and both outcomes appear side by side in the same preview panel, one badge green and the other red for the identical two colors.

That's not a bug in the guideline or a loophole to exploit carefully; it's the intended outcome of a rule built around a real legibility difference between big, bold letterforms and small, dense body copy. Confirm the size and weight of the text you're actually shipping before you approve a color on the strength of the large-text row alone, since a heading style that later gets reused at a smaller size or lighter weight needs to be re-checked against the stricter thresholds.5

When to use this

Use this guide when choosing or auditing a heading, label, or any large-text element, whenever you need to confirm a color against the correct large-text threshold instead of the stricter bar meant for body copy.

Examples

A muted slate heading color that passes the tool's Large Text row but fails its Normal Text row

Before
Foreground #808a9c, background #ffffff
After
The Large Text (24px Bold) row clears AA at roughly 3.5:1, while the Normal Text (16px) row fails, since both rows render side by side for the same pair and only the large-text threshold is low enough to pass here.

A darker gray that clears both rows, not just the large-text one

Before
Foreground #6b7280, background #ffffff
After
This pair clears the Normal Text (16px) row at AA as well as the Large Text (24px Bold) row, so it works as a heading or as body copy without needing a separate check for either.
Sources
  1. 1.

    W3C, "Understanding Success Criterion 1.4.3: Contrast (Minimum)," w3.org, accessed August 2026. https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html

  2. 2.

    MDN Web Docs, "font-weight," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight

  3. 3.

    WebAIM, "Contrast and Color Accessibility," webaim.org, accessed August 2026. https://webaim.org/articles/contrast/

  4. 4.

    W3C, "Web Content Accessibility Guidelines (WCAG) 2.1," w3.org, May 2025. https://www.w3.org/TR/WCAG21/

  5. 5.

    The A11Y Project, "Checklist," a11yproject.com, accessed August 2026. https://www.a11yproject.com/checklist/

FAQ