aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Design

Color Contrast & WCAG: A Guide to Accessible Design

No matter how elegant an interface looks, if its text can't be read, the design isn't doing its job. The color contrast WCAG rules turn exactly this concern into something measurable: they convert the brightness difference between text and its background into a numeric ratio, safeguarding legibility for people with low vision, age-related sight loss, or anyone squinting at a screen in bright sunlight. In this article I'll cover what a contrast ratio actually is, which thresholds are mandatory, and how to apply them practically in your day-to-day design work.

What exactly is a contrast ratio?

A contrast ratio is the relationship between the relative luminance of two colors. WCAG defines it with this formula:

contrast = (L1 + 0.05) / (L2 + 0.05)

Here L1 is the relative luminance of the lighter color and L2 that of the darker one. Luminance ranges from 0 (pure black) to 1 (pure white). The result lands between 1:1 (no difference) and 21:1 (black on white, the highest possible). The key point is that this ratio is based on brightness, not hue: a red and a green of equal luminance may look striking, yet have a poor contrast ratio.

The WCAG thresholds: 4.5:1 and 3:1

WCAG (Web Content Accessibility Guidelines) has two conformance levels, and most legal and corporate requirements target AA:

  • Normal text — AA: at least 4.5:1 (criterion 1.4.3).
  • Large text — AA: at least 3:1. "Large" means at least 18pt (≈24px), or bold 14pt (≈18.66px).
  • Normal text — AAA: at least 7:1 (criterion 1.4.6).
  • Large text — AAA: at least 4.5:1.

The logic: the larger and bolder the type, the wider its letter strokes, so it stays readable even at lower contrast. That gives you a little more freedom in headings, but you should never drop below 4.5:1 in body copy.

Not just text: UI elements and graphics

Here's a point many designers miss: contrast isn't only about text. The 1.4.11 Non-text Contrast criterion introduced in WCAG 2.1 also covers the interactive and information-bearing parts of an interface:

  • Button borders, form input outlines, focus rings;
  • The boundaries of controls like checkboxes and radio buttons;
  • Lines, icons, and map colors that carry meaning in a graphic.

All of these must hold at least 3:1 contrast against their neighboring colors. So if you put a slightly lighter-gray input border on a light-gray background, you're most likely violating this criterion. Focus indicators are especially critical: a keyboard user can only tell where they are from a visible focus ring.

Choosing colors in practice

A few habits make building an accessible palette dramatically easier:

  • Start from brightness, not hue. Keep your brand hue but adjust its lightness when needed. Tweaking the L value in HSL, or better still OKLCH, is the cleanest way to raise contrast.
  • Never encode meaning in color alone. "Green = success, red = error" isn't enough on its own; add an icon, label, or pattern for colorblind users. This is the point of criterion 1.4.1 (Use of Color).
  • Test both ends. A color that passes in light mode sits on a different background in dark mode. Measure in both themes.
  • Don't rely on placeholder text. Faint gray placeholders are almost always below 4.5:1; never use them as a substitute for a persistent label.

On the CSS side, giving dark-mode text a slightly softened tone instead of pure #000 (or pure white) both eases the eyes and keeps enough contrast:

:root {
  --text: #1a1a1a;      /* light theme, ~16:1 on white */
  --text-muted: #555;   /* still above 4.5:1 */
}
[data-theme="dark"] {
  --text: #e8e8e8;      /* ~13:1 on dark */
  --text-muted: #a0a0a0;
}

How do you measure and test contrast?

Eyeballing it isn't reliable; always verify with a tool:

  • WebAIM Contrast Checker — enter two hex values and see the AA/AAA verdict instantly.
  • Chrome/Edge DevTools — select a text element and open the color picker to read the contrast ratio and AA/AAA lines directly.
  • Lighthouse and axe DevTools — scan the whole page and list contrast failures; they can even hook into your CI pipeline.
  • Figma plugins (such as Contrast or Stark) — measure right on the artboard while you're still designing.

The ideal flow: verify the palette in Figma during design, add an automated check with axe or Lighthouse in code, so a regression gets caught before it ships.

Frequently Asked Questions

Do I have to hit 4.5:1 everywhere?

For body copy and small text, yes, it's mandatory if you want AA conformance. There are exceptions: purely decorative text (carrying no meaning), logos, and disabled UI elements are exempt from the contrast requirement. For large headings the threshold drops to 3:1.

Does dark mode solve contrast automatically?

No. Pure white text on a dark background can create a "halo" effect that hurts reading, while faint gray text easily falls below 4.5:1. Dark mode needs to be measured as rigorously as light mode.

Have the contrast rules changed between WCAG versions?

The core contrast thresholds (4.5:1, 3:1, 7:1) have been the same since WCAG 2.0. WCAG 2.1 added non-text contrast (1.4.11); 2.2 strengthened criteria around focus visibility. So the thresholds are fixed while the scope has widened.

Want an interface that's both sharp and readable for everyone? I can help you build a WCAG-compliant palette and design system without breaking your brand colors. Get in touch and let's review your project together.

Bu kategorideki tüm yazılar →

Devamı için