Starting from RGB instead of hex
RGB is usually where a colour arrives from in code — a canvas API, a colour picker's channel sliders, an image's pixel data — so converting RGB straight to HSL, without a hex string in between, is the more common path in practice. The maths is the same either way; only the input format changes.
Working the numbers on rgb(142, 68, 173)
Take the three channels: 142 (red), 68 (green), 173 (blue). The largest is blue at 173, the
smallest is green at 68. Lightness is their average: (173 + 68) / 2 = 120.5, and as a share of
255 that's about 47% — the l in hsl(282, 44%, 47%).
Saturation compares the gap between the largest and smallest channel (173 − 68 = 105) against
how far the lightness sits from the middle of the range; working that through gives roughly 44%,
a moderately saturated colour rather than a vivid one. Hue looks at blue being the largest channel
and where red and green fall relative to the 105-wide gap, landing at 282 degrees — solidly in the
purple band between blue (240°) and magenta (300°).
A dark example: rgb(0, 31, 63)
Low channel values across the board don't need a special case — the same steps apply. The largest
channel is blue (63), the smallest is red (0), so lightness is (63 + 0) / 2 = 31.5, about 12% of
255. That low lightness is what makes the colour read as a near-black navy rather than a mid-tone
blue, even though saturation comes out at a full 100% — full saturation just means no grey is
mixed in, it says nothing about how light or dark the result looks.
When two channels tie for the maximum
rgb(0, 200, 200) has green and blue tied at 200, both above red's 0, which puts the colour
exactly on the boundary between the green and blue thirds of the wheel: hsl(180, 100%, 39%), a
cyan. rgb(200, 0, 200), red and blue tied above green, lands at hsl(300, 100%, 39%), a
magenta. Neither case needs special handling — the same largest-channel rule picks out 180 and 300
without any averaging, because a tie at the maximum still leaves one channel clearly at the
minimum, which is all the formula needs to place the hue precisely.
Adjusting a colour: RGB versus HSL
| Task | In RGB | In HSL |
|---|---|---|
| Make it 20% lighter | Recompute all three channels toward 255 | Add roughly 20 to the l value |
| Make it less vivid | Blend all three channels toward their average | Lower the s value |
| Pick a related colour | Not directly possible | Add or subtract degrees from h |
| Store it exactly | Three integers, 0–255 each | Three numbers on three different scales |
RGB is compact and exact, which is why formats and file headers store colour that way. HSL trades
a little of that compactness for channels that map onto the questions a person actually asks about
a colour — how light, how vivid, which hue — which is why it's the format most style systems
expose as variables for exactly this reason: a design token like --brand-l: 47% can be tuned on
its own without anyone recomputing red, green and blue by hand.