C

CSS Handbook

Clean • Professional

CSS Color Module Level 4+

9 minute

CSS Color Module Level 4+

The CSS Color Module Level 4+ adds modern color spaces—Lab, LCH, HWB, and OKLCH—that go beyond rgb() and hsl(). They provide wider gamuts, more accurate colors, and better accessibility.

As of 2025, all major browsers support them, making these formats ready for production use in modern, future-proof web design.

Lab Color Space

The Lab Color Space (CIELAB) is one of the most important updates introduced in the CSS Color Module Level 4. Unlike rgb() or hsl(), which are device-dependent, Lab is perceptually uniform, meaning it represents colors the way humans actually see them.

Syntax:

color: lab(80% 20 -10);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lab Color Space Example</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 20px;
      background: #f4f4f4;
    }

    h1 {
      text-align: center;
      margin-bottom: 20px;
    }

    .color-box {
      width: 200px;
      height: 120px;
      margin: 20px auto;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 1.2em;
      font-weight: bold;
    }

    /* Lab color applied */
    .lab-example {
      background-color: lab(80% 20 -10);
    }

    .description {
      max-width: 600px;
      margin: 0 auto;
      text-align: justify;
      line-height: 1.6;
      font-size: 1.05em;
    }
  </style>
</head>
<body>
  <h1>CSS Lab Color Space Example</h1>

  <div class="color-box lab-example">
    Lab(80% 20 -10)
  </div>

  <div class="description">
    <p>
      The box above uses the <strong>Lab color space</strong> in CSS:
      <code>lab(80% 20 -10)</code>. Here, the lightness is set to <b>80%</b>, 
      with a slight shift toward <b>red</b> on the <code>a</code> axis and a 
      subtle move toward <b>blue</b> on the <code>b</code> axis.  
    </p>
    <p>
      Unlike traditional <code>rgb()</code> or <code>hsl()</code>, 
      Lab colors ensure that design adjustments are <b>consistent and 
      human-friendly</b>, making them ideal for branding, 
      accessibility, and high-fidelity design systems.
    </p>
  </div>
</body>
</html>

LCH Color Space

The LCH Color Space is part of the CSS Color Module Level 4 and is considered one of the most designer-friendly formats. LCH stands for:

  • L (Lightness): brightness of the color (0% = black, 100% = white).
  • C (Chroma): color intensity or vividness (higher = more saturated).
  • H (Hue): the angle on the color wheel, measured in degrees (0–360).

Syntax:

color: lch(80% 40 130);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>LCH Color Space Example</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f9f9f9;
      padding: 20px;
    }

    h1 {
      text-align: center;
      margin-bottom: 20px;
    }

    .color-box {
      width: 200px;
      height: 120px;
      margin: 20px auto;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 1.2em;
      font-weight: bold;
    }

    /* LCH color applied */
    .lch-example {
      background-color: lch(80% 40 130);
    }

    .description {
      max-width: 650px;
      margin: 0 auto;
      text-align: justify;
      line-height: 1.6;
      font-size: 1.05em;
    }
  </style>
</head>
<body>
  <h1>CSS LCH Color Space Example</h1>

  <div class="color-box lch-example">
    LCH(80% 40 130)
  </div>

  <div class="description">
    <p>
      The box above uses the <strong>LCH color space</strong> in CSS:
      <code>lch(80% 40 130)</code>. Here, the lightness is set to <b>80%</b>, 
      chroma at <b>40</b> gives moderate saturation, and hue <b>130°</b> 
      produces a greenish color tone.
    </p>
    <p>
      Unlike <code>hsl()</code>, LCH is based on human perception, ensuring 
      that color adjustments feel <b>natural, balanced, and accessible</b>. 
      Designers can rely on it for branding, gradients, and data visualization 
      where consistency is critical.
    </p>
  </div>
</body>
</html>

HWB Color Space

The HWB Color Space (Hue, Whiteness, Blackness) is another modern addition in CSS Color Module Level 4. It’s designed to be simple and intuitive, especially for designers who think about colors like mixing paints.

  • Hue (H): the angle on the color wheel (0–360°).
  • Whiteness (W): how much white is mixed in (0–100%).
  • Blackness (B): how much black is mixed in (0–100%).

Syntax:

color: hwb(120 20% 10%);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>HWB Color Space Example</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: #f7f7f7;
      padding: 20px;
    }

    h1 {
      text-align: center;
      margin-bottom: 20px;
    }

    .color-box {
      width: 200px;
      height: 120px;
      margin: 20px auto;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 1.2em;
      font-weight: bold;
    }

    /* HWB color applied */
    .hwb-example {
      background-color: hwb(120 20% 10%);
    }

    .description {
      max-width: 650px;
      margin: 0 auto;
      text-align: justify;
      line-height: 1.6;
      font-size: 1.05em;
    }
  </style>
</head>
<body>
  <h1>CSS HWB Color Space Example</h1>

  <div class="color-box hwb-example">
    HWB(120 20% 10%)
  </div>

  <div class="description">
    <p>
      The box above uses the <strong>HWB color space</strong> in CSS:
      <code>hwb(120 20% 10%)</code>. The hue <b>120°</b> creates a green base,
      while <b>20% whiteness</b> lightens it and <b>10% blackness</b> adds a
      slight dark tone.  
    </p>
    <p>
      Unlike <code>hsl()</code>, HWB is more natural for designers and
      illustrators, since it works like <b>mixing paint</b> — start with a pure
      hue, then add white or black. This makes it especially useful for creating
      subtle shades and tints without complex calculations.
    </p>
  </div>
</body>
</html>

OKLCH Color Space

The OKLCH Color Space is one of the newest and most advanced formats in CSS Color Module Level 4+. It’s based on OKLab, but expressed in cylindrical form, making it more intuitive for designers.

  • L (Lightness): brightness of the color (0% = black, 100% = white).
  • C (Chroma): color intensity or vividness.
  • H (Hue): position on the color wheel (0–360°).

Syntax:

color: oklch(80% 0.15 140);
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>OKLCH Color Space Example</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: #fafafa;
      padding: 20px;
    }

    h1 {
      text-align: center;
      margin-bottom: 20px;
    }

    .color-box {
      width: 220px;
      height: 120px;
      margin: 20px auto;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-size: 1.2em;
      font-weight: bold;
    }

    /* OKLCH color applied */
    .oklch-example {
      background-color: oklch(80% 0.15 140);
    }

    .description {
      max-width: 650px;
      margin: 0 auto;
      text-align: justify;
      line-height: 1.6;
      font-size: 1.05em;
    }
  </style>
</head>
<body>
  <h1>CSS OKLCH Color Space Example</h1>

  <div class="color-box oklch-example">
    OKLCH(80% 0.15 140)
  </div>

  <div class="description">
    <p>
      The box above uses the <strong>OKLCH color space</strong> in CSS:
      <code>oklch(80% 0.15 140)</code>. The lightness of <b>80%</b> makes it
      fairly bright, <b>0.15 chroma</b> adds moderate vividness, and the
      <b>140° hue</b> gives it a greenish tone.
    </p>
    <p>
      Unlike older formats such as <code>rgb()</code> or <code>hsl()</code>,
      OKLCH ensures that adjustments in lightness or chroma feel
      <b>consistent to the human eye</b>. This makes it ideal for 
      <b>accessible color palettes, data visualization, and brand design</b>.
    </p>
  </div>
</body>
</html>

Practical Use Cases

Accessible Contrast Ratios

Colors chosen in OKLCH maintain consistent brightness and contrast across devices. This ensures readability for everyone, especially for users with visual impairments.

.button {
  background: oklch(70% 0.2 200); /* Vibrant blue */
  color: oklch(95% 0.05 200); /* Near-white with high contrast */
}

Dynamic Theming (Light/Dark Mode)

With LCH, you can easily tweak lightness and chroma for different themes without losing visual harmony.

:root {
  --primary: lch(60% 50 200);
}
@media (prefers-color-scheme: dark) {
  :root {
    --primary: lch(70% 40 200); /* Adjusted for dark mode */
  }
}

Data Visualization

For heatmaps, charts, or graphs, OKLCH keeps color steps visually even so users can spot differences clearly.

.heatmap-step-1 { background: oklch(80% 0.1 100); }
.heatmap-step-2 { background: oklch(80% 0.1 120); }
.heatmap-step-3 { background: oklch(80% 0.1 140); }

Brand Consistency

Using Lab ensures colors remain accurate across screens, which is crucial for brand identity.

.brand-logo { background: lab(50% 30 -20); }

Softer, Eye-Friendly Themes

With HWB, you can mix in whiteness and blackness to create soft, balanced tones.

color: hwb(210 10% 20%);

CSS Color Module Level 4+ Demo (HTML + CSS)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Color Module Level 4+ Demo</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 40px;
      background: hwb(210 10% 20%);
      color: #222;
      line-height: 1.6;
    }

    h1, h2 {
      margin-bottom: 10px;
    }

    section {
      margin-bottom: 40px;
      padding: 20px;
      border-radius: 10px;
      background: #fff;
      box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    }

    /* 1. Accessible Contrast Ratios */
    .button {
      padding: 12px 24px;
      border: none;
      border-radius: 6px;
      font-size: 16px;
      cursor: pointer;
      background: oklch(70% 0.2 200);
      color: oklch(95% 0.05 200);
      transition: background 0.3s ease;
    }
    .button:hover {
      background: oklch(65% 0.22 200);
    }

    /* 2. Dynamic Theming */
    :root {
      --primary: lch(60% 50 200);
    }
    @media (prefers-color-scheme: dark) {
      :root {
        --primary: lch(70% 40 200);
      }
      body {
        background: hwb(210 20% 10%);
        color: #eee;
      }
    }
    .theme-box {
      background: var(--primary);
      color: white;
      padding: 20px;
      border-radius: 8px;
      text-align: center;
      font-weight: bold;
    }

    /* 3. Data Visualization */
    .heatmap {
      display: flex;
      gap: 10px;
    }
    .heatmap div {
      width: 80px;
      height: 80px;
      border-radius: 6px;
    }
    .heatmap-step-1 { background: oklch(80% 0.1 100); }
    .heatmap-step-2 { background: oklch(80% 0.1 120); }
    .heatmap-step-3 { background: oklch(80% 0.1 140); }

    /* 4. Brand Consistency */
    .brand-logo {
      width: 120px;
      height: 120px;
      background: lab(50% 30 -20);
      display: flex;
      justify-content: center;
      align-items: center;
      color: white;
      font-weight: bold;
      border-radius: 50%;
      font-size: 18px;
    }

    /* 5. Softer, Eye-Friendly Theme Example */
    .soft-box {
      padding: 20px;
      background: hwb(210 30% 10%);
      color: hwb(210 10% 60%);
      border-radius: 8px;
    }
  </style>
</head>
<body>

  <h1>🌈 CSS Color Module Level 4+ Demo</h1>
  <p>This page demonstrates modern color spaces: <b>Lab, LCH, HWB, OKLCH</b> with practical real-world examples.</p>

  <!-- 1. Accessible Contrast Ratios -->
  <section>
    <h2>1. Accessible Contrast Ratios</h2>
    <p>Using <b>OKLCH</b> for high contrast, WCAG-friendly buttons.</p>
    <button class="button">Accessible Button</button>
  </section>

  <!-- 2. Dynamic Theming -->
  <section>
    <h2>2. Dynamic Theming (Light/Dark Mode)</h2>
    <p>This box changes its primary color based on your system theme using <b>LCH</b>.</p>
    <div class="theme-box">Primary Theme Color</div>
  </section>

  <!-- 3. Data Visualization -->
  <section>
    <h2>3. Data Visualization with OKLCH</h2>
    <p>Colors stay visually even across steps, making charts clearer.</p>
    <div class="heatmap">
      <div class="heatmap-step-1"></div>
      <div class="heatmap-step-2"></div>
      <div class="heatmap-step-3"></div>
    </div>
  </section>

  <!-- 4. Brand Consistency -->
  <section>
    <h2>4. Brand Consistency with Lab</h2>
    <p>A brand logo with accurate color reproduction using <b>Lab</b>.</p>
    <div class="brand-logo">LOGO</div>
  </section>

  <!-- 5. Softer, Eye-Friendly Theme -->
  <section>
    <h2>5. Softer, Eye-Friendly Themes</h2>
    <p>Using <b>HWB</b> for painter-like soft tones in UI elements.</p>
    <div class="soft-box">
      This is a calm, eye-friendly design box.
    </div>
  </section>

</body>
</html>

Example: Accessible Button with OKLCH

OKLCH ensures better contrast and readability across devices and themes.

<button class="btn">Click Me</button>
.btn {
  background: oklch(65% 0.15 200);
  color: oklch(95% 0.05 200);
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.3s;

  @media (prefers-color-scheme: dark) {
    background: oklch(75% 0.12 200);
    color: oklch(20% 0.05 200);
  }

  &:hover {
    background: oklch(70% 0.18 200);
  }
}

Converting Between Color Spaces

Example with JavaScript (culori)

import { rgb, lch } from 'culori';

const lchColor = lch(rgb('#007bff'));
// { l: ~48, c: ~68, h: ~243 }

const rgbColor = rgb(lch({ l: 48, c: 68, h: 243 }));
// { r: ~0, g: ~123, b: ~255 }

CSS Fallback

Not all environments support modern color spaces yet, so always add a fallback:

.element {
  background: rgb(0, 123, 255); /* Fallback */
  background: lch(48% 68 243);  /* Modern */
}


Article 0 of 0