DevToolsmith

Color Contrast Checker

Check whether text and background colors are readable enough for WCAG 2.2 AA and AAA. Enter colors in any CSS format, see a live preview, and get the closest color in the same hue that passes.

Runs 100% in your browser — nothing is uploaded

Large text (24px)

Normal text (16px). The quick brown fox jumps over the lazy dog. Body copy needs at least 4.5:1 to pass AA.

Small print (12px) is hard to read even when it passes.

Button
4.75:1Good
AANormal text4.5:1✓ Pass
AALarge text3:1✓ Pass
AAANormal text7:1✗ Fail
AAALarge text4.5:1✓ Pass
AAUI components and icons3:1✓ Pass

Large text is at least 24px (18pt), or 18.66px (14pt) bold. The ratio is truncated, not rounded, so 4.499:1 never shows as a pass.

Closest passing colors (same hue)

AAA
Text rgb(100 116 139) on rgb(255 255 255)

WCAG contrast requirements

ContentAA (minimum)AAA (enhanced)Criterion
Normal text4.5:17:11.4.3 / 1.4.6
Large text (≥ 24px, or ≥ 18.66px bold)3:14.5:11.4.3 / 1.4.6
UI components, focus rings, icons, chart lines3:1–1.4.11
Disabled controls, logos, decorationNo requirement–

Common colors on white

ColorRatioAA textAA largeNote
#767676 4.54:1 Pass Pass The lightest gray that passes AA on white
#777777 4.47:1 Fail Pass Looks the same, but fails AA (4.47:1)
#595959 7.00:1 Pass Pass The lightest gray that passes AAA on white
#64748b 4.75:1 Pass Pass Tailwind slate-500
#9ca3af 2.53:1 Fail Fail Tailwind gray-400, a common placeholder color
#3b82f6 3.67:1 Fail Pass Tailwind blue-500
#2563eb 5.16:1 Pass Pass Tailwind blue-600
#ff6600 2.93:1 Fail Fail Bright orange

Fixing low contrast

  • Change lightness, not hue. The suggestions above keep the OKLCH hue and chroma and only move lightness, so the color still reads as your brand color.
  • Use one shade darker for text. In most palettes the 500 shade is for fills and the 600 or 700 shade is for text on white.
  • Check both themes. A gray that passes on white often fails on a dark background. Test each pair in light and dark mode.
  • Don’t rely on opacity. Gray text made with opacity: 0.6 changes contrast with every background it lands on. Use a solid color instead.

Checking contrast in code

JavaScript
// Colors as [r, g, b] in 0-255
function luminance([r, g, b]) {
  const lin = (c) => {
    c /= 255;
    return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
  };
  return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
}

function contrast(a, b) {
  const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
  return (hi + 0.05) / (lo + 0.05);
}

contrast([118, 118, 118], [255, 255, 255]);  // 4.54 -> passes AA

Automated checkers like axe-core and Lighthouse use the same formula. Need the color in another format? Open the color converter.

Frequently asked questions

What contrast ratio do I need for WCAG AA?

WCAG 2.2 level AA requires at least 4.5:1 for normal text and 3:1 for large text (24px, or 18.66px bold). User interface components, focus indicators and meaningful icons need 3:1 against adjacent colors (success criterion 1.4.11). Level AAA raises text to 7:1 and large text to 4.5:1.

How is the contrast ratio calculated?

Each color’s relative luminance L is computed from its linearised sRGB channels as 0.2126 R + 0.7152 G + 0.0722 B. The ratio is (L1 + 0.05) / (L2 + 0.05), with L1 the lighter color. It ranges from 1:1 (same color) to 21:1 (black on white). Translucent text is first blended with the background.

Why does #777 fail when it looks fine?

#777777 on white is 4.47:1, just under 4.5. WCAG thresholds are strict, so 4.49:1 fails. This tool truncates the ratio instead of rounding it, so a failing pair never displays as 4.5:1. The nearest passing gray is #767676 (4.54:1).

What about APCA and WCAG 3?

APCA is a newer contrast method being explored for WCAG 3. It accounts for font size and weight and for the difference between dark-on-light and light-on-dark text. WCAG 3 is still a draft, and laws and procurement rules (ADA, Section 508, EN 301 549) reference WCAG 2.x, so the 4.5:1 rule is what audits check today.

Do disabled buttons and logos need to pass?

No. WCAG exempts text in inactive (disabled) controls, purely decorative text, text in logos and brand names, and text that is part of a picture with significant other content. Placeholder text in form fields is not exempt, and is a very common failure.