ESC

Type to search the knowledge base.

Do Not Rely on Color Alone

WCAG use of color — convey status with text, icons, and patterns so color-blind and low-vision users aren’t locked out.

beginner3 min read
  • accessibility
  • do-not

WCAG 1.4.1 Use of Color requires that color is not the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. Red borders alone for errors fail this for many users.

Docs: Understanding 1.4.1, WebAIM.

Common failures

Pattern Fix
Error = red outline only Text message + icon + aria-invalid
Required = red asterisk only Asterisk + “required” in label/legend
Charts series by color only Patterns, labels, direct labeling
Links only by color Underline or strong weight difference
Status pills green/red only Text: Success / Failed

Forms

<!-- Bad: only border color changes -->
<input class="error" />

<!-- Better -->
<label for="email">Email</label>
<input id="email" aria-invalid="true" aria-describedby="email-err" />
<p id="email-err">
  <span aria-hidden="true">⚠ </span>Enter a valid email.
</p>

See accessible forms errors.

article a {
  color: var(--link);
  text-decoration: underline;
}

If design removes underlines, ensure 3:1 contrast against surrounding text and another cue (icon, weight) — underline remains the simplest robust cue.

Data viz

<ul>
  <li><span class="swatch swatch-a" aria-hidden="true"></span> Desktop — 62%</li>
  <li><span class="swatch swatch-b" aria-hidden="true"></span> Mobile — 38%</li>
</ul>

Direct labels on chart segments beat a color-only legend.

Instructions

Avoid: “Click the green button.”
Prefer: “Click Continue.”

Color blindness is not one thing

Deuteranomaly, protanopia, tritanopia differ. Patterns + text work across types; simulating one filter isn’t full proof but helps design review.

Relation to contrast

Use of color is separate from contrast minimums. You can pass contrast and still fail use-of-color if meaning is only hue. You can provide icons and still fail contrast on text.

Footguns

  1. Success/error toast color-only.
  2. Calendar free/busy only by shade.
  3. Password strength meter color-only.
  4. Map pins distinguished only by color.

Interview out-loud answer

“I never convey meaning with color alone — I add text, icons, or patterns. Errors need messages, links need underlines or equivalent cues, and charts need labels. Contrast is a separate check.”

Status in tables and lists

A column of green/red dots for “healthy/unhealthy” needs a text equivalent in the cell or a second column (“Healthy”). aria-label on the dot can work if the cell still makes sense when SR reads the row in order — verify with a quick NVDA/VoiceOver pass.

Extra practice

Write a minimal demo in a scratch file or the playground: one happy path, one failure path, and one boundary input. If you cannot exhibit a bug that the pattern prevents, you do not own the concept yet — re-read the primary docs linked below and tighten the example until the failure is obvious.

Notes from real codebases

Teams that succeed here keep the rules mechanical: lint where possible, CI for the rest, and a short human checklist for what automation cannot see. Document exceptions with an owner name and a removal date so “temporary” escapes do not become permanent architecture.

Implementation notes

Wire this into real code on the next feature, not only a demo. Prefer the smallest change that encodes the rule — a shared helper, a lint rule, or a checklist item in the PR template. Revisit after a week of production traffic: if users or tests still hit the failure mode, the documentation (and the abstraction) are not sharp enough yet.

Further reading

Related guides