What Are Modern CSS Color Models?

Modern CSS color models, such as lch(), oklch(), and color(display-p3), allow web developers to access wider color gamuts, generate perceptually uniform palettes, and achieve richer color fidelity on contemporary screens. Unlike legacy formats like rgb(), hex, and hsl(), these newer functional notations separate perceived lightness from color intensity, making programmatic color manipulation, dynamic theme creation, and accessible contrast calculations significantly more reliable across modern browsers.

Legacy Color Formats vs Modern Spaces

For decades, the web relied predominantly on standard sRGB color formats: Hexadecimal codes, rgb(), and hsl(). While simple to implement, sRGB formats carry inherent limitations:

Modern color spaces resolve these issues by aligning mathematical representations of color with actual human visual perception.

Understanding LCH

The lch() functional notation represents color using three parameters:

.badge-alert {
  background-color: lch(65% 85 45);
}

Because lightness is independent of hue and chroma, adjusting the hue angle keeps the perceived brightness constant. However, CIELCH exhibits a known mathematical anomaly: shifting chroma in certain blue hues can cause an unintended shift toward purple.

The Advantages of OKLCH

Developed by Björn Ottosson, oklch() improves directly upon lch(). It uses the same fundamental parameters—Lightness, Chroma, and Hue—while fixing the hue-shift distortion found in standard CIELCH.

:root {
  --primary-color: oklch(0.65 0.22 250);
  --primary-hover: oklch(0.75 0.22 250);
}

oklch() is widely regarded as the premier choice for UI design systems and dynamic theming because increasing or decreasing lightness reliably changes brightness without altering the underlying perceived hue.

Wide Gamut with Display P3

display-p3 is a wide-gamut color space developed for modern digital displays. It covers roughly 50% more visible colors than standard sRGB, excelling particularly in vibrant greens and intense reds.

In CSS, Display P3 is accessed via the generic color() function:

.vibrant-banner {
  background-color: color(display-p3 1 0.2 0.3);
}

The parameters specify red, green, and blue coordinates as decimals from 0 to 1 (or percentages), mapped specifically to the P3 gamut.

Feature Comparison

Color Model Gamut Support Perceptually Uniform Primary Strength
hsl() sRGB No Legacy familiarity
lch() Unlimited (CIE LAB) Yes Direct lightness isolation
oklch() Unlimited (CIE LAB) Yes (Refined) Consistent palettes without hue shifts
display-p3 Wide P3 No Highly vibrant monitor output

Practical Implementation and Fallbacks

Modern browsers across desktop and mobile support oklch(), lch(), and color(display-p3). When building stylesheets for progressive enhancement, you can provide fallback declarations or use CSS conditional rules:

.button {
  background-color: rgb(0, 102, 204);
  background-color: oklch(0.55 0.2 245);
}

@supports (color: color(display-p3 0 1 0)) {
  .accent-element {
    color: color(display-p3 0.1 0.9 0.2);
  }
}

Adopting these modern color models allows developers to craft consistent, accessible, and vibrant visual experiences natively in CSS.