A comprehensive guide to using P3, oklch, and wide-gamut colors in modern web development
Traditional approach:
/* Standard RGB/Hex - limited to sRGB gamut */
color: #ff0000;
color: rgb(255, 0, 0);Limitations:
- Locked to sRGB color space (~35% of visible colors)
- Can't access P3's richer reds, greens, cyans
- Same values look different across color spaces
/* Rich, vibrant red in P3 */
color: color(display-p3 1 0 0);
/* Deep emerald green */
color: color(display-p3 0 0.8 0.3);
/* Vivid cyan - impossible in sRGB */
color: color(display-p3 0 1 1);
/* Comparison */
color: #ff0000; /* sRGB red - basic */
color: color(display-p3 1 0 0); /* P3 red - 25% more saturated */Browser support: Excellent (Safari, Chrome, Firefox modern versions)
/* Rich red */
color: oklch(0.6 0.25 25);
/* ↑ ↑ ↑
lightness chroma hue */
/* Deep saturated blue */
color: oklch(0.5 0.3 250);
/* Vibrant magenta */
color: oklch(0.7 0.32 330);Why oklch is great:
- Perceptually uniform (changing lightness looks consistent)
- Easy to create color variations
- Automatically uses widest available gamut
- Better for programmatic color generation
/* Similar to oklch but different coordinate system */
color: oklab(0.6 0.2 0.1);/* Older perceptual space */
color: lch(60% 130 25);@theme {
--color-brand-red: color(display-p3 1 0.1 0.1);
--color-vibrant-green: oklch(0.7 0.25 145);
--color-deep-cyan: color(display-p3 0 0.9 0.95);
}/* Fallback for older displays */
.button {
background: rgb(255, 50, 50); /* sRGB fallback */
}
/* P3 for capable displays */
@media (color-gamut: p3) {
.button {
background: color(display-p3 1 0.2 0.2);
}
}<style scoped>
.hero-title {
/* Fallback */
color: #ff3366;
/* P3 override for capable displays */
color: color(display-p3 1 0.2 0.4);
}
@supports (color: color(display-p3 1 0 0)) {
.accent {
background: color(display-p3 0 0.95 0.7);
}
}
</style>/* All "red" but different richness */
/* sRGB - basic web red */
color: rgb(255, 0, 0);
/* P3 - 25% more saturated red */
color: color(display-p3 1 0 0);
/* oklch - same perceptual red, uses best available gamut */
color: oklch(0.628 0.258 29.23);
/* Rec2020 - even wider (few displays support) */
color: color(rec2020 1 0 0);:root {
/* Define once with fallback */
--accent: rgb(220, 38, 38);
--accent: color(display-p3 0.9 0.15 0.15);
}/* oklch makes it easy to adjust saturation/lightness */
--base: oklch(0.6 0.2 25);
--lighter: oklch(0.7 0.2 25); /* just adjust L */
--more-vivid: oklch(0.6 0.3 25); /* just adjust C */Modern browsers show when colors are outside sRGB:
- Chrome/Safari DevTools show color space info
- Color picker indicates if P3/wide gamut
- Warning if color can't be displayed on current monitor
Important: Even with P3 CSS colors:
- User must have P3-capable display
- Browser must support it
- OS color management must be working
- On sRGB displays, colors get compressed back to sRGB
But it's progressive enhancement — specify rich colors, and users with capable displays see them in full glory, others get acceptable sRGB fallback.
| Color Space | Coverage of Visible Colors | Use Case |
|---|---|---|
| sRGB | ~35% | Legacy web, older content |
| Display P3 | ~45-50% | Modern displays, HDR content |
| Rec. 2020 | ~75% | Future displays, ultra-wide gamut |
Use color(display-p3 ...) for:
- Brand colors with RGB fallbacks
- Hero sections and accent colors
- Any color where vibrancy matters
Use oklch() when you need to:
- Programmatically manipulate colors
- Generate shades and tints
- Create color scales with consistent perception
- Build theme systems with predictable variations
| Function | Syntax Example | Best For |
|---|---|---|
| rgb() | rgb(255, 0, 0) | Legacy support |
| color(display-p3) | color(display-p3 1 0 0) | Wide gamut colors |
| oklch() | oklch(0.6 0.25 25) | Color manipulation |
| oklab() | oklab(0.6 0.2 0.1) | Perceptual mixing |
| lch() | lch(60% 130 25) | Lab-based colors |
To verify your P3 colors are working:
- Use a P3-capable display (modern MacBook Pro, iPad Pro, iPhone)
- Open DevTools and inspect the element
- Check if color picker shows "Display P3" indicator
- Compare with sRGB version side-by-side
- Test fallback behavior on non-P3 displays
- MDN Web Docs: Comprehensive CSS color documentation
- OKLCH Color Picker: oklch.com - Interactive tool for exploring oklch colors
- Can I Use: Check browser support for color functions
- Webkit Blog: Articles on wide gamut colors in Safari
Generated on January 5, 2026