CSS Color Spaces Explained: sRGB, Display-P3, OKLCH
Understand when and why to use different color spaces in web design. Practical guidance for wider gamut colors and perceptual uniformity.
- Understand when and why to use different color spaces in web design.
- What Are Color Spaces.
- sRGB vs Display-P3 vs Rec.2020.
- OKLCH and Perceptual Uniformity.
- Practical CSS Implementation.
What Are Color Spaces
A color space defines the range of colors (gamut) that can be represented. The web historically used only sRGB β a relatively narrow space from 1996. Modern displays, especially Apple devices since 2015 and premium Android screens, support Display-P3, covering ~25% more colors than sRGB. This means vibrant reds, greens, and blues previously impossible on the web are now displayable. CSS supports multiple color spaces through the color() function, oklch(), lab(), and lch(), letting designers access wider gamut colors.
sRGB vs Display-P3 vs Rec.2020
sRGB is the legacy standard β hex, rgb(), and hsl() all operate within it. Itβs safe and universal. Display-P3 is a wider gamut: color(display-p3 1 0 0) produces a red more vivid than anything sRGB can express. Rec.2020 is even wider, used in HDR video β web support is emerging. For most designers, Display-P3 is the actionable upgrade: use it for hero images, brand colors, and accents where extra vibrancy makes a visible difference. The improvement is subtle but noticeable on supported displays.
OKLCH and Perceptual Uniformity
OKLCH isnβt about wider gamut β itβs about perceptual uniformity. In sRGB, a gradient from blue to yellow passes through muddy gray because mathematical interpolation doesnβt match human perception. OKLCH handles this correctly. The practical impact: better gradients, more balanced palettes, and predictable lightness adjustments. When you set oklch(0.7 0.15 hue), every hue at that lightness actually looks equally bright β unlike HSL where βsame lightnessβ produces wildly different perceived brightness.
Practical CSS Implementation
Implement wide gamut with progressive enhancement. Define colors in sRGB first, then override: --brand: #FF3366; --brand: oklch(0.65 0.25 10);. Browsers that support oklch use the richer color; older browsers fall back. For gradients, specify interpolation: background: linear-gradient(in oklch, var(--from), var(--to));. This produces smooth gradients instead of muddy RGB defaults. The Color Converter translates between all color spaces.