Color Accessibility

Color Contrast and WCAG: A Practical Guide

What contrast ratios mean, the WCAG AA and AAA levels for text and UI, and how to fix colors that fail without losing your palette.

By ColorOverflow Editorial TeamUpdated November 8, 20266 min readBeginner

Color contrast is the difference in lightness between two colors, such as text and its background. Too little of it and text becomes hard or impossible to read, for people with low vision, for anyone on a phone in bright sunlight, and for everyone on a cheap screen. WCAG, the Web Content Accessibility Guidelines, turns that into numbers you can check: normal text needs a contrast ratio of at least 4.5:1, and large text at least 3:1.

This guide explains what those numbers mean, which parts of a design they apply to, and how to fix a color that fails without starting your palette again.

What a contrast ratio is

A contrast ratio compares how light two colors appear to the human eye. It runs from 1:1, the same color on itself, to 21:1, black on white. The higher the number, the easier the pair is to tell apart.

The ratio uses each color's relative luminance, a measure of perceived lightness in which green counts for far more than blue. The formula is (lighter + 0.05) divided by (darker + 0.05). You never need to work it out by hand, but it explains a common surprise: a bright yellow and a bright blue can look equally strong, yet white text is easy to read on the blue and almost invisible on the yellow.

The WCAG levels: AA and AAA

WCAG 2.2 is the current version of the standard. It defines two levels for text contrast. Level AA is the one most websites, apps and accessibility laws aim for. Level AAA is stricter, and is worth reaching for long reading text and for audiences with low vision.

  • AA, normal text: at least 4.5:1.
  • AA, large text: at least 3:1.
  • AAA, normal text: at least 7:1.
  • AAA, large text: at least 4.5:1.

Large text means at least 18 point, or 14 point bold. On the web that is about 24px for regular text and about 18.66px for bold. Anything smaller is normal text, which includes almost all body copy, labels and buttons.

The limits are exact. A pair at 4.46:1 does not round up to 4.5:1, so it fails AA for normal text.

Examples that pass and fail

Colors that look perfectly readable to you can still fall short. These pairs show how close the line can be.

  • White text on indigo #6366F1: 4.46:1. Fails AA for normal text, passes for large text.
  • White text on a deeper indigo #4F46E5: 6.28:1. Passes AA.
  • White text on orange #F97316: 2.80:1. Fails, even for large text.
  • Dark navy #0F172A text on the same orange: 6.36:1. Passes AA.
  • Gray #767676 text on white: 4.54:1. Just passes AA, and it's about the lightest gray that does.
  • Gray #94A3B8 text on white: 2.56:1. A common placeholder gray, and it fails.

The orange example shows a useful trick. A bright, light color often can't carry white text, but it works well with dark text. Switching the text color can fix a pair without touching your brand color.

Not just text: buttons, icons and charts

WCAG also asks for a contrast of at least 3:1 for the parts of an interface people need to see to use it. This is called non-text contrast, and it covers:

  • The borders of input fields and checkboxes, when the border is what shows where the control is.
  • Icons that carry meaning on their own, such as a search or close icon without a text label.
  • Focus indicators and the states of controls, such as a selected tab or a toggled switch.
  • Lines, bars and slices in charts that people need to read the data.

A very light gray input border on white is one of the most common failures. #CBD5E1 on white, for example, is only 1.48:1.

Read the full guideDashboard and Data Visualization Color Palettes

What the rules don't cover

  • Logos and text that is part of a logo or brand name.
  • Purely decorative text and elements that carry no information.
  • Disabled controls. They still need to be recognizable as controls, so don't make them disappear completely.
  • Text inside a photo or picture that also has other significant visual content.

Placeholder text in form fields is not exempt when it carries information. If a placeholder is the only hint about what to type, treat it as text and give it 4.5:1.

Don't rely on color alone

About 1 in 12 men and 1 in 200 women have some form of color vision deficiency, most often difficulty telling red from green. A separate WCAG rule says color must never be the only way information is shown. Good contrast helps, but it doesn't replace a second signal.

  • Add an icon or text to errors, warnings and success messages, not just a red or green color.
  • Underline links in body text, or make them clearly different in more than hue.
  • Label chart lines directly, or use patterns and shapes as well as colors.
  • Mark required form fields with text or a symbol, not only a colored border.
Read the full guideDesigning for Color Blindness: Palettes, Patterns and Testing

How to fix a color that fails

A failing pair rarely means throwing your palette away. Usually a small change in lightness is enough.

  1. Darken or lighten one color, keeping its hue. A slightly deeper version of a brand color often passes and still looks like the brand.
  2. Swap the text color. Try dark text on light and bright colors, and white text on deep ones.
  3. Keep a bright brand color for large elements, such as headings, banners and illustrations, where 3:1 is enough.
  4. Add a darker shade of the color to your palette for text and small details, and keep the bright one for backgrounds and accents.
  5. Recheck after every change. A pair that passed can fail again when you adjust its neighbor.

The Contrast Checker does the first step for you. Enter a text and a background color, and when a level fails it suggests the nearest colors that pass, with the same hue and only the lightness changed.

Contrast CheckerTest a text and background pair against WCAG AA and AAA.
  • #0F172A
  • #4F46E5
  • #C2410C
  • #F1F5F9
  • #FFFFFF

White text passes AA on the indigo (6.28:1) and on the burnt orange (5.17:1), and the navy text reaches 16.29:1 on the light gray.

Open in generatorPalette detailsVisualize

Palette GeneratorPick a color, apply a harmony rule and refine your palette.Read the full guideHow to Build an Accessible UI Color Palette

Common mistakes

  • Light gray text for a softer look, which often drops below 4.5:1.
  • White text on bright yellow, orange, green or light blue buttons.
  • Text placed over photos without an overlay, so contrast changes across the image.
  • Checking contrast in light mode only, and not in dark mode.
  • Rounding a ratio up, such as treating 4.46:1 as 4.5:1.
  • Testing only the main text color and forgetting links, placeholders and secondary text.
Read the full guideAccessible Text on Colored Backgrounds, Images and Dark Mode

Quick checklist

  1. Body text and labels reach at least 4.5:1 against their background.
  2. Large headings reach at least 3:1.
  3. Input borders, meaningful icons, focus rings and chart elements reach at least 3:1.
  4. Links, errors and statuses use more than color to stand out.
  5. Every theme you ship, light and dark, has been checked.

Contrast is easiest to get right at the start. Check your palette's pairs while you choose colors, then test the palette on a real layout before you build with it.

Palette VisualizerSee your palette on real designs, outfits and rooms.

Put it into practice

Unsaved changes

“” has changes that aren't saved to your wishlist. Save them before continuing?