The short answer

Accessible color is not a separate concern you bolt on at the end - it is the difference between a design that works for everyone and one that works for people with your eyesight, your screen, and your lighting. The single most important measure is contrast: how distinct foreground is from background. Get contrast right and most of accessibility follows.

Contrast and WCAG

The Web Content Accessibility Guidelines (WCAG) define contrast as a ratio between two colors, from 1:1 (identical) to 21:1 (black on white). The thresholds that matter:

  • 4.5:1 - normal body text, to meet level AA.
  • 3:1 - large text (roughly 24px+, or 19px+ bold) and meaningful UI elements like icons and input borders.
  • 7:1 - the stricter AAA level for body text, worth aiming for on reading-heavy screens.

These are not suggestions in most contexts - accessibility law in many countries references WCAG AA directly.

Never color alone

Roughly 8% of men and 0.5% of women have some form of color vision deficiency. If the only thing separating "error" from "success" is red versus green, those users see two identical grays.

  • Pair color with an icon, a label, or a shape - a red field with an alert icon and text, not just a red border.
  • Do not use color as the sole indicator of state, selection, or meaning.
  • Test your screens through a colorblindness simulator - most design tools have one built in.

Dark mode

Dark mode is not an inverted light theme. Pure white text on pure black vibrates and fatigues the eye; pure-black shadows disappear. Doing it well means:

  • Soften the extremes. Off-white text (not #fff) on a dark gray (not #000) reads more comfortably.
  • Rethink elevation. In light mode shadows show depth; in dark mode, lighter surfaces do. A raised card is a slightly lighter gray.
  • Desaturate. Saturated colors glow uncomfortably on dark backgrounds - pull them back and re-check contrast, which behaves differently against dark.

This is exactly where semantic tokens pay off: color.text.primary is one value in light mode and another in dark, and every screen follows.

An accessible palette

Build the palette as tested pairs, not isolated swatches. A color is not "accessible" on its own - only against the background it sits on. Decide the background/foreground combinations up front, verify each meets the ratio, and store them as tokens so nobody hand-picks an untested pair later.

Checking your work

  • Contrast checkers (WebAIM, or the one built into Figma and browser devtools) give you the exact ratio for any pair.
  • Browser DevTools flag low-contrast text and simulate vision deficiencies.
  • Test in real conditions - a phone at minimum brightness, outdoors. The lab is not where your users read.