π― HEX vs RGB vs HSL vs OKLCH: Which Color Format to Use in CSS (2026)
#6366f1 works. But does it make sense? If you're building a design system β especially one with light and dark modes, theming, or dynamic color β your choice of color format determines how easily you can create variations, compute accessible contrasts, and generate palettes programmatically. Here's the data on each format, including the new OKLCH standard that fixes the biggest problem in CSS color.
The Perceptual Uniformity Problem (Why HSL Is Broken)
Here's the core issue with HSL: two colors with the same L (lightness) value do NOT have the same perceived brightness. A pure yellow at hsl(60, 100%, 50%) appears dramatically brighter than a pure blue at hsl(240, 100%, 50%). This is because HSL uses a simple mathematical transformation of RGB, not a model calibrated to human vision. The result: when you build a palette by varying only lightness in HSL, some colors look much darker or lighter than intended, throwing off visual hierarchy.
This isn't a minor nitpick. It's the reason why design systems built on HSL palettes often need manual adjustments β the developer creates blue-500: hsl(220, 60%, 50%) and yellow-500: hsl(50, 60%, 50%), and the yellow is unreadably bright while the blue is fine. The research team behind OKLCH (led by BjΓΆrn Ottosson) measured this with human subjects and designed a color space where equal L values actually look equally bright to human observers.
Format-by-Format Comparison
HEX (#RRGGBB) β Universal Default
Strengths: Compact (7 bytes), universally supported (CSS 1, 1996), easy to copy-paste from every design tool. Every design tool exports HEX. Every developer recognizes it. Limitations: No transparency support (use 8-digit hex #RRGGBBAA, but it's rarely used and confusing to read). No programmatic color manipulation β you can't say "make this color 20% darker" in HEX without converting to another format. Not human-readable β you can't look at #6366f1 and know it's indigo-purple.
RGB / RGBA β Developer Standard
Strengths: Maps directly to how screens work (red, green, blue subpixels). Easy to manipulate with JavaScript (Math.round(r * 0.8) to darken). RGBA adds alpha transparency. Used in WebGL, Canvas, and every image processing library. Limitations: Not perceptually meaningful β changing one channel changes perceived brightness unpredictably. No hue/saturation model, making palette creation harder.
HSL β Designer-Friendly but Flawed
Strengths: Maps to how humans naturally describe color ("a dark, desaturated blue"). Creating monochromatic palettes is trivial β same H and S, different L. Easy to programmatically generate variations. Limitations: The perceptual uniformity issue described above. Also, HSL's saturation axis behaves oddly at extreme lightness values β a very light color at S=100% can look almost white, confusing the expected relationship between S and vividness.
OKLCH β The Modern Standard
OKLCH (Oklab Lightness, Chroma, Hue) is a polar-coordinate version of the Oklab color space, designed to be perceptually uniform across all hues and lightness levels. Key advantages:
- Uniform L:
oklch(50% 0.2 270)(blue) has the same perceived brightness asoklch(50% 0.2 90)(yellow-green). No surprises when building palettes. - Predictable C (Chroma): Unlike HSL saturation, chroma maps linearly to colorfulness.
C=0is always neutral gray.C=0.1is always slightly tinted. This makes theming and dark-mode generation predictable. - Wide gamut: OKLCH can express colors outside the sRGB gamut that modern displays (Display P3, Rec. 2020) can render but HEX/RGB/HSL cannot.
Browser support: 94.3% as of January 2026 (Can I Use data). The only holdouts: older iOS Safari versions (pre-15.4), Opera Mini, and KaiOS Browser. For production, use with a HEX fallback:
:root {
--color-primary: #6366f1; /* Fallback for older browsers */
--color-primary: oklch(55% 0.23 270); /* OKLCH for modern browsers */
}
CSS custom properties cascade: the last valid declaration wins. Modern browsers use OKLCH; old browsers ignore it and use HEX.
Decision Table
| Use Case | Recommended Format | Reason |
|---|---|---|
| Quick design tool copy-paste | HEX | Universal export format |
| Design system / token library | OKLCH (with HEX fallback) | Perceptually uniform, predictable |
| Dynamic theming (JS/React) | HSL or OKLCH | Easy programmatic variations |
| Canvas / WebGL generation | RGB | Hardware-native, every API accepts it |
| Maximum compatibility | HEX | Works since CSS 1, 1996 |
| Dark mode generation | OKLCH | Predictable lightness control |
The practical advice: use OKLCH (with a HEX fallback) for your design tokens in 2026. If OKLCH is too new for your team, use HSL β just be aware of its perceptual quirks and manually adjust colors that look off. Use the Color Picker to explore values in all formats and see how the same color translates across HEX, RGB, HSL, and OKLCH.
Found this helpful? Explore 100+ free online tools β no signup needed.