Introduction
CSS color is evolving beyond hex and RGB. oklch() and color-mix() offer perceptual uniformity, wider gamut support, and dynamic color manipulation directly in stylesheets.
oklch gives you a color space where equal numeric changes produce equal visual changes — unlike HSL where perceived brightness varies wildly across hues. Ideal for consistent palettes.
color-mix() blends colors in any color space, creating dynamic variants without preprocessors or JavaScript.
Key Concepts
oklch()
/* oklch(lightness chroma hue) */
.button {
background: oklch(0.6 0.2 250); /* Vibrant blue */
color: oklch(0.98 0 0); /* Near white */
}
.overlay { background: oklch(0.2 0 0 / 0.8); }
color-mix()
.lighter { background: color-mix(in oklch, var(--primary), white 30%); }
.darker { background: color-mix(in oklch, var(--primary), black 20%); }
.muted { color: color-mix(in oklch, var(--text), transparent 40%); }
Relative Color Syntax
.hover-state {
background: oklch(from var(--primary) calc(l - 0.1) c h);
}
Practical Examples
1. Consistent Palette
:root {
--hue: 250;
--primary-50: oklch(0.97 0.02 var(--hue));
--primary-500: oklch(0.6 0.2 var(--hue));
--primary-900: oklch(0.3 0.12 var(--hue));
}
2. Dynamic Hover States
.button {
--btn-bg: oklch(0.6 0.2 250);
background: var(--btn-bg);
}
.button:hover { background: color-mix(in oklch, var(--btn-bg), white 15%); }
.button:active { background: color-mix(in oklch, var(--btn-bg), black 15%); }
3. Accessible Text Colors
.dark-bg {
background: oklch(0.25 0.05 250);
color: oklch(0.95 0.02 250);
}
Best Practices
- oklch for palette generation — equal lightness = equal perceived brightness.
- color-mix() for hover/active states instead of hardcoded values.
- Define base hue as a custom property for theme switching.
- Use oklch color space in color-mix() for uniform blending.
- Provide sRGB fallbacks for older browsers.
Common Pitfalls
- Chroma >0.3 may be out of sRGB gamut — gets clipped.
- oklch hues don't match HSL hues — different color spaces.
- Not providing fallbacks before oklch values.
- Over-engineering: static colors are fine as hex.
Browser Support
oklch(): Chrome 111+, Safari 15.4+, Firefox 113+. color-mix(): Chrome 111+, Safari 16.2+, Firefox 113+. Relative color: Chrome 119+, Safari 16.4+, Firefox 128+. ~90% for core features.
Related Guides
- CSS Custom Properties — combine variables with color functions
- Color Theory for Developers — understand color relationships
- CSS Blend Modes — layer colors for complex effects