Snippets / Accessibility /

Color-Blind Safe Palette

Status indicators that rely on red/green alone fail for ~8% of male users. Use symbol + color pairs and safe hue choices in oklch() so every status remains distinguishable regardless of color vision type.

Status badges — symbol + color, never color alone
✓ Success ⚠ Warning ✕ Error ℹ Info
Safe 4-hue palette (blue · orange · teal · red-orange)
h265
h50
h195
h25
Widely Supported
a11yno-js

Quick implementation

/* Color-blind safe status palette using oklch hues.
   Safe hue choices: blue (265), orange (50), teal (195), red-orange (25).
   Avoid: pure red (h=25 alone) vs pure green (h=145 alone) —
   indistinguishable for ~8% of male users with deuteranopia. */

:root {
  /* Status tokens — hue-safe, same lightness */
  --status-success: oklch(0.52 0.16 195); /* teal — not pure green */
  --status-warning: oklch(0.60 0.20 50);  /* orange */
  --status-error:   oklch(0.52 0.18 25);  /* red-orange */
  --status-info:    oklch(0.52 0.22 265); /* blue */
}

/* ALWAYS pair color with a non-color indicator */
.badge--success::before { content: "✓ "; }
.badge--warning::before { content: "⚠ "; }
.badge--error::before   { content: "✕ "; }
.badge--info::before    { content: "ℹ "; }

/* Or use aria-label for the state name */
/*  */

/* Chart lines — use both color AND stroke dash pattern */
.chart-line--a { stroke: var(--status-info);    stroke-dasharray: none; }
.chart-line--b { stroke: var(--status-success); stroke-dasharray: 8 4; }
.chart-line--c { stroke: var(--status-warning); stroke-dasharray: 2 4; }

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are an accessibility-focused CSS developer. Design a color-blind safe status palette using oklch().

Requirements:
1. Define four status colors as CSS custom properties using oklch(). Use hues that remain distinguishable for deuteranopia (red-green), protanopia (red-green), and tritanopia (blue-yellow):
   - Success: teal (h≈195) rather than pure green (h≈145) — pure green is confused with red in deuteranopia.
   - Warning: orange (h≈50) — high luminance, distinct from blue and teal.
   - Error: red-orange (h≈25) — more orange than pure red for better deuteranopia discrimination.
   - Info: blue (h≈265) — universally distinguishable across all common color vision deficiencies.
2. Create status badge components that ALWAYS pair color with a text symbol: ✓, ⚠, ✕, ℹ — so meaning is never conveyed by color alone (WCAG 1.4.1).
3. Show how to simulate color blindness in Chrome DevTools: Rendering → Emulate vision deficiencies.
4. Show the SVG stroke-dasharray technique for distinguishing chart lines without relying on color.
5. Explain that pure red (#ff0000 / oklch green h=145) vs pure green (#00ff00 / h=145 at different L) are the most commonly confused pair — about 8% of males have some form of red-green color vision deficiency.

Constraints:
- WCAG 1.4.1 (Use of Color): Color must not be the ONLY visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
- Keep all four status colors at approximately the same oklch lightness (L≈0.52–0.60) so they have similar visual weight.
- Do not use pure oklch(0.65 0.25 145) as a success color — it reads as pure green and fails deuteranopia.

Output CSS custom properties, badge components, and a brief explanation of which hues are safe and why.

Why this matters in 2026

Approximately 8% of men and 0.5% of women have some form of color vision deficiency — predominantly red-green (deuteranopia or protanopia). A success/error system that uses only green and red is invisible as a distinction to these users. WCAG 1.4.1 (Level A) explicitly requires that color not be the only visual means of conveying information. This affects every status badge, alert banner, form validation state, chart legend, and traffic-light indicator in every web application — a very wide surface area that is frequently overlooked.

The logic

The safest hue choices for a four-color palette are: blue (~h265), orange (~h50), teal (~h195), and red-orange (~h25). These four remain perceptually distinct under deuteranopia and protanopia simulation. The key insight is that the problematic axis is the red-green distinction — shifting from pure red (h=25) to red-orange and from pure green (h=145) to teal (h=195) moves both colors off the confused axis. Always reinforce color with a non-color indicator: icon symbols (✓ ⚠ ✕ ℹ), text labels, border styles, or SVG stroke patterns for charts.

Accessibility & performance

Test your palette using Chrome DevTools Rendering → Emulate vision deficiencies (Deuteranopia, Protanopia, Tritanopia, Achromatopsia). For data visualizations, also consider luminance contrast between chart elements — elements should differ in lightness even when hue information is unavailable. Using oklch() makes this systematic: keep chroma high but vary hue, and ensure lightness values differ by at least 0.15 between any two elements that need to be distinguishable. There is zero performance cost to color token choices.