Adjust Text Color to Match Background Contrast

Mix text color toward black or white based on the background to maintain WCAG contrast. Combine color-mix() with light-dark() for full theme awareness.

Advanced

Detailed Explanation

Deriving Readable Text Colors

When a background color is dynamic (user-themed, data-driven, randomly generated), the foreground text color also has to adapt. color-mix() gives you a clean expression for that adaptation:

.chip {
  background: var(--bg-color);
  color: color-mix(in oklch, var(--bg-color), white 92%);
}

This produces text that lives in the same hue family as the background but is pulled most of the way toward white — typically enough contrast for body copy on a mid-tone background.

A more robust pattern: light-dark()

For real production use, combine with the new light-dark() function:

.chip {
  background: var(--bg-color);
  color: light-dark(
    color-mix(in oklch, var(--bg-color), black 92%),
    color-mix(in oklch, var(--bg-color), white 92%)
  );
}

Now the text picks black-on-light in light mode and white-on-dark in dark mode automatically.

Verify with WCAG

color-mix() does not check contrast for you. Always run candidate foreground/background pairs through the accessibility color checker and target at least 4.5:1 for body text and 3:1 for large/UI text.

Limits

For arbitrary hue backgrounds you may still need a deliberate high-contrast text token (--text-on-brand: #fff). Use color-mix() for derived UI surfaces and reserve hardcoded text-on-color tokens for brand-critical pairs.

Use Case

User-generated themes, data-driven chips/badges, color-coded calendars, and any UI where the background is decided at runtime and the text must remain readable.

Try It — CSS color-mix() Generator

Open full tool