What HSL means
HSL describes a color the way people often talk about one:
- Hue, an angle on the color wheel from 0° to 360°: 0 is red, 120 green, 240 blue.
- Saturation, from 0% (gray) to 100% (as vivid as the hue gets).
- Lightness, from 0% (black) through the pure hue at 50% to 100% (white).
It is a reshuffle of RGB, not a new color space. Every HSL value maps to exactly one sRGB color, and CSS supports it everywhere: hsl(262 83% 58%).
Converting by hand
Take #7C3AED, a bright violet. In RGB that is 124, 58, 237, or 0.4863, 0.2275 and 0.9294 after dividing by 255.
- Max and min. max = 0.9294 (blue), min = 0.2275 (green). The difference Δ is 0.7020.
- Lightness is the midpoint: (0.9294 + 0.2275) ÷ 2 = 0.5784, so L = 58%.
- Saturation = Δ ÷ (1 − |2L − 1|) = 0.7020 ÷ (1 − 0.1569) = 0.8326, so S = 83%.
- Hue. Blue is the largest channel, so H = 60 × ((R − G) ÷ Δ + 4) = 60 × (0.3687 + 4) = 262°.
Result: hsl(262 83% 58%). The panel under the readouts shows these steps for your own code.
Why HSL is handy
HSL makes some edits easy. Keep hue and saturation and move lightness, and you get tints and shades of one color. Keep saturation and lightness and rotate the hue, and you get a sibling color of a similar strength. That is why design systems and CSS custom properties often store colors as separate H, S and L numbers:
:root { --brand-h: 262; --brand-s: 83%; }
.button { background: hsl(var(--brand-h) var(--brand-s) 58%); }
.button:hover { background: hsl(var(--brand-h) var(--brand-s) 50%); }
Where HSL lies to you
HSL lightness is a formula, not a measure of how bright a color looks. The strip in the tool makes this visible. At hsl(60 100% 50%) you get pure yellow, and at hsl(240 100% 50%) pure blue. Both have L = 50%, yet the yellow is glaringly bright and the blue is dark.
The numbers back that up. In OKLCH, a space designed to track perceived lightness, the yellow measures 96.8% and the blue 45.2%. Against white, the yellow has a contrast ratio of 1.07:1 (unreadable) and the blue 8.59:1.
This matters when you:
- build a palette by rotating hue and expect the colors to feel equally strong;
- generate hover or disabled states by subtracting lightness;
- assume text with the same L will have the same contrast.
Enter OKLCH
OKLCH has the same three ideas (lightness, chroma, hue) but measured perceptually. The bottom row of the strip keeps your OKLCH lightness constant across six hues, and the colors look much more evenly bright. Modern CSS supports it in every current browser: oklch(54.1% 0.247 293) is the same violet as above.
Use HSL when you need wide compatibility or when a tool only speaks HSL. Use OKLCH when you need predictable lightness, for example when generating scales. The shades generator and the Tailwind color generator both work in OKLCH for that reason.
HSL versus HSV (HSB)
Design apps such as Photoshop and Figma show HSB or HSV in their pickers, which is a different model. In HSV, 100% "value" with 100% saturation is the pure hue, while in HSL the pure hue sits at 50% lightness. For #7C3AED, HSL is 262°, 83%, 58% and HSV is 262°, 75.5%, 92.9%. The hue is always the same; the other two numbers are not interchangeable. The tool shows both so you can paste into whichever field you have.
Related tools
For all formats at once, including Lab, HWB and color(), use the color converter. To pick a color visually with HSV controls, open the HEX color picker. For the RGB step alone, see HEX to RGB.
FAQ
What is the HSL of pure gray?
Saturation 0%. Hue is undefined and written as 0 by convention. #808080 is hsl(0 0% 50.2%).
Do I need commas in hsl()?
No. The modern syntax uses spaces, hsl(262 83% 58%), and adds alpha after a slash, hsl(262 83% 58% / 0.5). The comma form hsl(262, 83%, 58%) still works everywhere.
Why does converting HSL back to HEX sometimes change the last digit?
Rounding. HSL is usually shown as whole numbers, and 360 × 100 × 100 steps don't line up exactly with 256 × 256 × 256 RGB values. Keep decimals if you need a lossless round trip.