What is HSL? The intuitive color format for designers and programmers
Use HSL when you need to programmatically generate color variations (hover states, accessible color palettes, dark mode variants). Use hex or rgb() for static, hand-picked colors where the mental model doesn't matter. Modern CSS also supports lch() and oklch(), which are perceptually uniform improvements over HSL and worth learning for new projects.
HSL (Hue, Saturation, Lightness) describes colors the way people naturally think about them rather than the way screens produce them. Hue is the base color on a 0-360 degree wheel (0 = red, 120 = green, 240 = blue). Saturation is the color intensity from 0% (gray) to 100% (vivid). Lightness is the brightness from 0% (black) to 100% (white), with 50% being the pure hue.
By TechCompare · Updated
How this is calculated
HSL's killer feature is that you can reason about color relationships in your head. Want a lighter version of a color? Increase the L value. Want a more muted version? Decrease S. Want a complementary color? Add 180 to H and wrap at 360. These mental operations are nearly impossible in RGB or hex. This makes HSL ideal for programmatic color generation, design system token derivation, and dynamic theming. In CSS the syntax is hsl(H S L) or hsl(H S L / A) for alpha. CSS Color Level 4 added the modern comma-free form and made hsl() accept space-separated values, so `hsl(220 80% 55% / 0.6)` is valid in all modern browsers as of 2026. A common real pattern in design systems is using HSL to generate hover states from a base brand color: a button at `hsl(220 80% 55%)` becomes `hsl(220 80% 45%)` on hover and `hsl(220 70% 65%)` on disabled. Three of the four numbers stay the same, which is what makes the relationship visible to the next engineer reading the code. The honest limitation of HSL is that it is not perceptually uniform. A lightness value of 50% maps to very different perceived brightness for yellow (which looks much brighter) versus blue (which looks darker), and saturation at 100% maps to different perceived intensity across hues. This is why modern CSS also offers lch() and oklch(), which fix the same problem by being grounded in the CIE CAM02 uniform color space. For static, hand-picked colors HSL is fine. For auto-generated scales, dark mode variants, and accessibility-critical contrast work, OKLCH is the better default in 2026.
Verdict
HSL's structure (Hue 0-360, Saturation and Lightness 0-100%) maps to the way people think about color relationships: a complement is +180 to hue, a tint is +X to lightness, a shade is -X to lightness, a mute is -X to saturation. That means a design system from hsl(220 80% 55%) can derive hover (hsl(220 80% 45%)) and disabled (hsl(220 70% 65%)) by changing one number, which is the whole point of the model. The honest limitation is that 50% lightness maps to very different perceived brightness across hues (yellow reads bright, blue reads dark), so auto-generated HSL scales don't look evenly spaced. That's where OKLCH and lch() take over for design tokens, dark mode variants, and accessibility-critical contrast work, since they're grounded in a perceptually uniform color space and the same numeric step feels consistent across every hue.
