OKLCH & Modern CSS Color: The Practical Guide
OKLCH describes color with three perceptual values — Lightness, Chroma, Hue — where equal numbers mean equal appearance. That single property turns palette work from hand-correction into computation: even ramps, predictable contrast, dark themes derived instead of re-picked. This hub collects our guides on the color model and what it changes in practice; the one-image version is a ramp with genuinely even steps.
The problem it solves
Older models like HSL describe how RGB numbers combine, not how colors look. The result is familiar to anyone who has generated a palette: steps that bunch in the middle, hues that drift, one column of the palette passing contrast while its neighbor fails at the “same” lightness. When lightness means what it says, those problems stop being craft and become arithmetic.
OKLCH vs HSL demonstrates the lightness lie with concrete color pairs, and What Is Perceptual Uniformity? explains the property underneath: equal numeric distance means equal visible difference. What Is a JND adds the measurement that turns “these two look the same” into a testable claim.
What changes in practice
With a perceptual model underneath, a palette becomes a set of curves
rather than a set of picks: a lightness curve places the steps, a chroma
profile shapes where saturation peaks, and the same machinery derives dark
themes and checks contrast. You rarely write oklch() values by hand — the
model is the engine under the palette, and the values surface in generated
tokens and in CSS when you need to reason about a color.
That engine role is how Scale Composer uses it: one scale drives color, typography and grid together, and the color side is computed in OKLCH so the ramps come out even without per-hue correction. The curve-based way of working has its own hub — color scales treats lightness curves and chroma profiles as design decisions in their own right — and the dark mode hub covers the derivation side: a dark theme computed by adjusting lightness and chroma rather than inverting anything.
Gamuts: the honest catch
Not every lightness-chroma-hue combination exists on a screen. Chroma has a ceiling that depends on lightness and hue, and wider-gamut P3 displays raise it. Good palette generation respects the ceiling with headroom instead of clipping against it — several guides below cover what that means for brand accents and imagery. sRGB vs Display-P3 maps the two gamuts and where wide-gamut screens actually are today, and Gamut Clipping shows what happens when a generated color exceeds the ceiling. Contrast is the other hard boundary a generated palette must respect; the contrast hub covers how to verify it.
Where to start reading
What Is OKLCH? is the ground-up introduction — start there if the three axes are new, then take What Is Chroma? for the one axis with no everyday-language equivalent. On the implementation side, The CSS oklch() Syntax covers writing the values, Converting Hex to OKLCH covers moving an existing palette in and out, and Browser Support for oklch() settles whether you can ship it without a build step (you can, natively, in all major browsers). Two guides then apply the model to problems that look unrelated until the model exposes them: Why Your Grays Aren’t Really Neutral on the residual chroma hiding in most gray scales, and Should Color Ramps Shift Hue? on when a hue drift is a bug and when it is a decision.
Guides in this hub
- Browser Support for oklch() in 2026
OKLCH browser support in 2026: every major engine has shipped oklch() since 2023. Who is still on the long tail, and the cheap fallbacks that cover them.
- Color Spaces Explained for Designers
Color spaces explained for designers: sRGB, P3 and Rec.2020 are gamuts, OKLCH and HSL are coordinate systems — and which combination fits which job.
- Converting Hex to OKLCH (and Back)
Converting hex to OKLCH is lossless; the way back can clamp. How the pipeline works, why the asymmetry exists, and a worked ramp from one real brand hex.
- Gamut Clipping: Why Your Colors Get Crushed
Gamut clipping crushes colors that exist in the model but not on screen: why channel clamping shifts hue, why ramps go flat, and how headroom prevents it.
- OKLCH in Tailwind v4
Tailwind OKLCH, in practice: v4 rebuilt its palette in OKLCH and moved config into CSS. How to define custom brand colors in @theme — and what that buys you.
- OKLCH vs HSL: Why HSL Lies About Lightness
OKLCH vs HSL: HSL's lightness is a fraction of RGB numbers, not a measure of perception — yellow and blue at 50% differ wildly. What OKLCH fixes, and how.
- OKLCH vs LAB and LCH
OKLCH vs LAB and LCH: what the 1976 and 2020 perceptual color spaces share, how OKLab fixed CIELAB's blue hue shift, and when each is the right tool.
- Should Color Ramps Shift Hue?
Color ramp hue shift, explained: why hand-tuned palettes rotated hue, why OKLCH makes constant hue look constant, and when rotation is a deliberate choice.
- sRGB vs Display-P3: What Designers Need to Know
sRGB vs Display-P3: what a gamut is, where P3's extra colors live, why hex can't express them, and when wide gamut is worth the effort in real projects.
- The CSS oklch() Syntax Explained
A practical reference for CSS oklch() syntax: the three values and alpha, worked button examples, relative colors with oklch(from …), and fallbacks.
- What Is a JND — When Two Colors Look the Same
The just noticeable difference color scientists measure: the smallest change an eye can reliably detect. Why palette steps within 0.02 OKLCH lightness merge.
- What Is Chroma (and How Is It Not Saturation)?
Chroma measures colorfulness absolutely; saturation is a percentage of whatever a hue allows. Why the difference matters for palettes and accent colors.
- What Is OKLCH? A Designer's Explanation
OKLCH describes color with three values that match human perception: lightness, chroma, hue. Learn why it replaced HSL for palettes, ramps and contrast.
- What Is Perceptual Uniformity?
Perceptual uniformity means equal numeric distances look like equal visible differences. Why RGB and HSL fail the test, and what uniformity buys design work.
- Why Your Grays Aren't Really Neutral
A neutral gray color with equal RGB channels often reads cold next to a brand palette. Why perception shifts grays, and how a whisper of chroma fixes it.
Start from your own color
The model makes the most sense with a color you care about: drop a brand color into Scale Composer and it suggests supporting colors derived from it — then watch the ramps it builds hold their lightness steps across every hue. That behavior is OKLCH, seen rather than explained.