Modern CSS Color
Use modern color spaces like oklch, color-mix, and relative color syntax
What you'll learn
Write colors in hex, rgb, hsl, and oklch notation
Understand why oklch and oklab are perceptually uniform
Use color-mix() to blend colors in any color space
Apply relative color syntax with the from keyword
Use currentColor and system colors for theme integration
Check color contrast against WCAG guidelines
Set color-scheme and handle forced-colors mode
Color Formats Compared
/* Legacy formats */
.element {
color: #6366f1;
} /* hex */
.element {
color: rgb(99, 102, 241);
} /* rgb */
.element {
color: rgba(99, 102, 241, 0.8);
} /* rgb with alpha */
.element {
color: hsl(239, 84%, 67%);
} /* hsl */
/* Modern formats */
.element {
color: oklch(59% 0.19 275);
} /* oklch — modern, perceptual */
.element {
color: oklab(59% 0.06 -0.18);
} /* oklab */
oklch — Perceptually Uniform
OKLCH stands for Lightness-Chroma-Hue. Unlike HSL, equal changes in values look equal to the human eye.
/* oklch(L C H) — L 0-100%, C 0-0.4, H 0-360 */
:root {
--indigo: oklch(59% 0.19 275);
--indigo-light: oklch(75% 0.13 275); /* same hue, lighter */
--indigo-dark: oklch(35% 0.15 275); /* same hue, darker */
--gray: oklch(50% 0.01 275); /* same hue, 0 chroma = gray */
}
color-mix() function
Mix two colors in any color space.
.button {
/* Mix white into indigo at 40% */
background: color-mix(in oklch, #6366f1 60%, white);
/* Equal mix in srgb */
border-color: color-mix(in srgb, #6366f1, #ef4444);
/* Tinted with transparency */
box-shadow: 0 2px 8px color-mix(in oklch, #6366f1 30%, transparent);
}
Relative Color Syntax
Derive new colors from existing ones using the from keyword.
:root {
--primary: #6366f1;
--primary-light: oklch(from var(--primary) calc(l + 15%) c h);
--primary-dark: oklch(from var(--primary) calc(l - 15%) c h);
--primary-muted: oklch(from var(--primary) l calc(c * 0.3) h);
}
currentColor & System Colors
currentColor inherits the element's text color. System colors respect OS theme.
.card {
color: #1e293b;
}
.card .icon {
fill: currentColor;
} /* matches parent text color */
/* System colors — adapt to user's OS */
@media (forced-colors: active) {
.card {
border: 2px solid CanvasText;
}
.btn {
background: ButtonFace;
color: ButtonText;
}
}
Color Contrast & WCAG
| Level | Ratio | Applies to |
|---|---|---|
| AA | 4.5:1 | Normal text (< 18px) |
| AA Large | 3:1 | Text >= 18px bold or >= 24px |
| AAA | 7:1 | All text |
/* Use high-contrast colors for accessibility */
.btn-primary {
background: oklch(55% 0.2 275); /* AA pass against white */
color: white; /* contrast ratio ~5.5:1 */
}
color-scheme
Tell the browser what color schemes your page supports.
:root {
color-scheme: light dark;
}
<meta name="color-scheme" content="light dark" />
This enables native form controls, scrollbars, and default colors to match the scheme.
Create a Color Palette with OKLCH
Code
html
1<div class="palette-demo">2<!-- Create 3 swatches with oklch colors -->3</div>This palette demo creates three color swatches using `oklch()`. OKLCH is perceptually uniform — lightness stays consistent across hues, unlike hex or RGB.
Key Takeaways
oklch() and oklab() are perceptually uniform — use for design systems
color-mix() blends colors in any color space with proportional mixing
Relative color syntax (from) derives new colors from existing references
currentColor inherits text color — useful for SVG icons
WCAG requires 4.5:1 contrast for normal text (AA)
color-scheme meta signals light/dark support to the browser