Fundamentals AccessibilityWCAGContrastA11y

Accessibility & Contrast in OKLCH

Master accessible design with OKLCH. Learn how perceptually uniform colors make it easier to meet WCAG contrast requirements and create inclusive user interfaces.

Accessibility & Contrast in OKLCH

Creating accessible color combinations is crucial for inclusive web design. OKLCH makes this significantly easier thanks to its perceptually uniform lightness values.

Why OKLCH Improves Accessibility

Traditional color spaces like HSL make it difficult to predict contrast ratios because their lightness values don't match human perception. OKLCH solves this by using perceptually uniform lightness.

The Simple Rule

Lightness difference of ≥0.40 typically ensures WCAG AA compliance (4.5:1 contrast) Lightness difference of ≥0.50 typically ensures WCAG AAA compliance (7:1 contrast)

/* AA Compliant - 0.40+ difference */
.aa-compliant {
  background: oklch(0.95 0.02 270);  /* Light background */
  color: oklch(0.30 0.04 270);       /* Dark text: 0.65 difference ✓ */
}

/* AAA Compliant - 0.50+ difference */
.aaa-compliant {
  background: oklch(0.98 0.01 270);  /* Very light background */
  color: oklch(0.20 0.03 270);       /* Very dark text: 0.78 difference ✓ */
}

Common Accessible OKLCH Patterns

Light Theme Text

:root {
  /* Backgrounds */
  --bg-primary: oklch(0.98 0.00 0);
  --bg-secondary: oklch(0.95 0.01 270);
  
  /* Text - all have 0.40+ difference from backgrounds */
  --text-primary: oklch(0.25 0.02 270);     /* 0.73 difference */
  --text-secondary: oklch(0.45 0.03 270);   /* 0.53 difference */
  --text-tertiary: oklch(0.60 0.03 270);    /* 0.38 difference - use carefully */
}

Dark Theme Text

@media (prefers-color-scheme: dark) {
  :root {
    /* Backgrounds */
    --bg-primary: oklch(0.15 0.02 270);
    --bg-secondary: oklch(0.20 0.03 270);
    
    /* Text - lightness values flipped */
    --text-primary: oklch(0.90 0.02 270);    /* 0.75 difference */
    --text-secondary: oklch(0.70 0.03 270);  /* 0.55 difference */
    --text-tertiary: oklch(0.55 0.03 270);   /* 0.40 difference */
  }
}

Interactive Elements

/* Buttons with accessible contrast */
.button-primary {
  background: oklch(0.45 0.20 250);    /* Dark blue */
  color: oklch(0.98 0.05 250);         /* Light text: 0.53 difference ✓ */
}

.button-primary:hover {
  background: oklch(0.55 0.22 250);    /* Lighter on hover */
  color: oklch(0.98 0.05 250);         /* Same text: 0.43 difference ✓ */
}

Building Accessible Palettes

Create a full palette where every combination is accessible:

:root {
  /* Base colors */
  --blue-100: oklch(0.90 0.08 250);
  --blue-300: oklch(0.70 0.15 250);
  --blue-500: oklch(0.50 0.20 250);
  --blue-700: oklch(0.30 0.18 250);
  --blue-900: oklch(0.20 0.12 250);
  
  /* Accessible combinations */
  /* blue-100 (0.90) + blue-700 (0.30) = 0.60 difference ✓ */
  /* blue-300 (0.70) + blue-900 (0.20) = 0.50 difference ✓ */
}

.light-background {
  background: var(--blue-100);
  color: var(--blue-700);  /* Accessible */
}

.dark-background {
  background: var(--blue-900);
  color: var(--blue-300);  /* Accessible */
}

Focus Indicators

/* Accessible focus ring */
.interactive {
  outline: 2px solid oklch(0.45 0.25 250);  /* Vivid blue */
  outline-offset: 2px;
}

/* Ensure contrast with background */
.light-theme .interactive:focus {
  outline-color: oklch(0.40 0.22 250);  /* Darker for light backgrounds */
}

.dark-theme .interactive:focus {
  outline-color: oklch(0.70 0.25 250);  /* Lighter for dark backgrounds */
}

Color Blind Considerations

While OKLCH doesn't directly address color blindness, it makes it easier to ensure sufficient brightness contrast:

/* Even without hue distinction, lightness provides differentiation */
.success {
  background: oklch(0.70 0.18 140);  /* Light green */
  color: oklch(0.25 0.10 140);       /* Dark text */
}

.error {
  background: oklch(0.70 0.20 25);   /* Light red */
  color: oklch(0.25 0.12 25);        /* Dark text */
}

/* Both have similar lightness (0.70 bg, 0.25 text) so even color-blind 
   users can read the text, and the lightness difference helps distinguish */

Testing Tools

  1. Browser DevTools - Built-in contrast checker
  2. WebAIM Contrast Checker - Online tool
  3. Rule of thumb - Check lightness difference ≥ 0.40

Summary

OKLCH makes accessible color design straightforward:

✅ Lightness difference ≥0.40 for AA compliance
✅ Lightness difference ≥0.50 for AAA compliance
✅ Works across light and dark themes
✅ Predictable contrast ratios

Next steps: