Skip to main content

Clean Gradients

Browsers now support perceptually uniform color blending.
┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  THE EVOLUTION OF WEB COLOR                                     │
│                                                                 │
│  1996-2011 (Old)              2022-Present (Modern)             │
│  ────────────────             ─────────────────────             │
│                                                                 │
│  Colors:                      Colors:                           │
│  - rgb(), rgba()              - oklch(), oklab()                │
│  - hsl(), hsla()              - lab(), lch()                    │
│  - #RRGGBB                    - color-mix()                     │
│                                                                 │
│  Blending:                    Blending:                         │
│  - sRGB only                  - Choose your space               │
│  - Muddy middle               - Clean transitions               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Gradient Comparison

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  BLUE (H=230) TO GREEN (H=130)                                  │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. LEGACY sRGB                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ ████▓▓▓▓▒▒▒▒░░░░░░░░░░░░▒▒▒▒▓▓▓▓████                    │   │
│  │ BLUE  muddy  GRAY   muddy  GREEN                         │   │
│  │       teal  (dull)  olive                                │   │
│  └─────────────────────────────────────────────────────────┘   │
│  Problem: Center is desaturated, feels "dirty"                  │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  2. OKLAB (Cartesian)                                           │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ ████████████████████████████████████████████████        │   │
│  │ BLUE   teal   CYAN   aqua   GREEN                        │   │
│  │       clean  (neutral) clean                             │   │
│  └─────────────────────────────────────────────────────────┘   │
│  Center may be slightly less saturated, but feels CLEAN         │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  3. OKLCH (Shorter Hue)                                         │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ ████████████████████████████████████████████████        │   │
│  │ BLUE   TEAL   CYAN   AQUA   GREEN                        │   │
│  │  ^       ^      ^      ^       ^                         │   │
│  │ Same saturation throughout!                              │   │
│  └─────────────────────────────────────────────────────────┘   │
│  ALL intermediate colors have SAME CHROMA                       │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  4. OKLCH (Longer Hue) - Rainbow Effect                         │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │ ██▓▓▒▒░░██▓▓▒▒░░██▓▓▒▒░░██▓▓▒▒░░██▓▓▒▒░░██▓▓▒▒░░██     │   │
│  │ BLUE PURPLE RED ORANGE YELLOW LIME GREEN                 │   │
│  │  ^                                                  ^    │   │
│  │  └──────── Passes through ENTIRE SPECTRUM ─────────┘    │   │
│  └─────────────────────────────────────────────────────────┘   │
│  Use sparingly - dramatic rainbow effect                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Hue Direction

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  WHEN USING OKLCH, HUE CAN GO TWO WAYS                          │
│                                                                 │
│  Given: Red (H=30) to Blue (H=250)                              │
│                                                                 │
│                        0/360                                    │
│                          |                                      │
│                     Red  *  (30 deg)                            │
│                        /                                        │
│                       /  SHORTER = 140 degrees                  │
│                      /   (through 0/360 = magenta)              │
│   270 ──────────────+────────────── 90                          │
│                      \                                          │
│                       \  LONGER = 220 degrees                   │
│                        \ (through 180 = cyan/green)             │
│                     Blue *  (250 deg)                           │
│                          |                                      │
│                         180                                     │
│                                                                 │
│  "shorter hue" = takes the smaller arc (default)                │
│  "longer hue"  = takes the larger arc (rainbow)                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

When to Use Each Space

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  DECISION GUIDE                                                 │
│                                                                 │
│  ┌──────────────────────────────┬────────────────────────────┐ │
│  │ Scenario                     │ Use                        │ │
│  ├──────────────────────────────┼────────────────────────────┤ │
│  │ Defining identity colors     │ OKLCH                      │ │
│  │                              │                            │ │
│  │ Mixing with black/white      │ OKLCH                      │ │
│  │                              │                            │ │
│  │ Creating color palettes      │ OKLCH                      │ │
│  │ with hue rotation            │                            │ │
│  │                              │                            │ │
│  │ Mixing with transparency     │ OKLAB                      │ │
│  │                              │                            │ │
│  │ Blending between arbitrary   │ OKLAB                      │ │
│  │ colors                       │                            │ │
│  │                              │                            │ │
│  │ Gradients between different  │ OKLAB                      │ │
│  │ hues                         │                            │ │
│  │                              │                            │ │
│  │ Legacy browser support       │ sRGB with rgba()           │ │
│  └──────────────────────────────┴────────────────────────────┘ │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Lightening a Color

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  HOVER STATE: LIGHTEN BLUE                                      │
│                                                                 │
│  Original:  ████████████████████████  oklch(55% 0.15 230)       │
│                                                                 │
│  Mix with white at 15%:                                         │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  L: 55% ────────────────────────> ~62% (lighter)        │   │
│  │                                                         │   │
│  │  C: 0.15 ───────────────────────> ~0.13 (less saturated)│   │
│  │                                                         │   │
│  │  H: 230 ────────────────────────> 230 (same hue)        │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Result:    ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  Lighter, same hue        │
│                                                                 │
│  This is CORRECT for a hover state.                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Adding Transparency

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  MUTED STATE: ADD TRANSPARENCY TO BLUE                          │
│                                                                 │
│  Original:  ████████████████████████  oklch(55% 0.15 230)       │
│                                                                 │
│  Mix with transparent at 80% using OKLAB:                       │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  Why OKLAB for transparency?                            │   │
│  │                                                         │   │
│  │  - More predictable with transparency                   │   │
│  │  - Avoids hue discontinuities near zero chroma          │   │
│  │  - Cleaner result                                       │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Result:    ░░░░░░░░░░░░░░░░░░░░░░░░  20% visible, same hue     │
│                                                                 │
│  Use OKLAB when mixing with transparency.                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Browser Support

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  MODERN COLOR SUPPORT (~94% of browsers)                        │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  oklch() / oklab()     Supported since 2022-2023        │   │
│  │  ──────────────────    Chrome 111+, Firefox 113+        │   │
│  │                        Safari 15.4+, Edge 111+          │   │
│  │                                                         │   │
│  │  color-mix()           Supported since 2022-2023        │   │
│  │  ─────────────         Chrome 111+, Firefox 113+        │   │
│  │                        Safari 16.2+, Edge 111+          │   │
│  │                                                         │   │
│  │  Gradient in oklab     Supported since 2022-2023        │   │
│  │  ──────────────────    Chrome 111+, Firefox 121+        │   │
│  │                        Safari 16.2+, Edge 111+          │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  FALLBACK STRATEGY:                                             │
│  ──────────────────                                             │
│                                                                 │
│  Provide an sRGB fallback for older browsers:                   │
│                                                                 │
│  1. First: sRGB gradient (works everywhere)                     │
│  2. Then:  OKLAB gradient (overrides in modern browsers)        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Key Takeaways

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│  SUMMARY                                                        │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                         │   │
│  │  1. Modern CSS supports OKLAB/OKLCH natively            │   │
│  │                                                         │   │
│  │  2. Use "in oklab" for gradients between hues           │   │
│  │                                                         │   │
│  │  3. Use "in oklch" when you need constant saturation    │   │
│  │                                                         │   │
│  │  4. "shorter hue" = default, minimal arc                │   │
│  │     "longer hue"  = rainbow, dramatic                   │   │
│  │                                                         │   │
│  │  5. OKLCH for lightening/darkening                      │   │
│  │     OKLAB for transparency mixing                       │   │
│  │                                                         │   │
│  │  6. ~94% browser support (2024)                         │   │
│  │                                                         │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  The web now has tools for perceptually clean gradients.        │
│  No more muddy middle.                                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘