Guide
HEX, RGB and HSL: how color actually works on the web
HEX, RGB and HSL aren't three kinds of color — they're three ways of writing down the same color. Converting between them never loses or gains anything about what the color actually is; what changes is which single number you'd need to nudge to get the edit you want.
One color space, two coordinate systems
RGB describes a color the way a screen produces it: how much red, green and blue light to fire, each on a 0–255 scale. That range isn't arbitrary — it's one byte per channel, the reason "255" shows up everywhere in graphics and the reason 8-bit color has 256 levels per channel. HEX is exactly RGB, just written in base 16 instead of base 10: two hex digits per channel, #RRGGBB, with no information added or removed by writing it that way.
HSL takes the identical RGB color and re-describes it in cylindrical coordinates: Hue as an angle around a color wheel (0–360°), Saturation as how far from grey it is, Lightness as how far from black or white it is. It is a transform of RGB, not an alternative to it — every RGB triple maps to exactly one HSL triple and back, with nothing lost in either direction.
Why HSL is easier to edit
"Make this ten percent darker" or "same hue, less saturated" or "the complementary color for this" are each a one-number change in HSL: adjust Lightness, adjust Saturation, or add 180° to Hue. The identical edits in RGB require moving all three channels together, by amounts that aren't obvious from looking at the numbers — there's no single red/green/blue slider that means "darker" without also risking a hue shift if you get the three amounts slightly wrong relative to each other.
That's the whole reason HSL exists alongside RGB rather than replacing it: RGB is what the screen wants, HSL is what a human editing a color by hand wants, and converting between them — which is exactly what this tool does — is how you get to use whichever one fits the task in front of you.
The alpha channel, and a genuinely useful gotcha
An 8-digit hex color adds a fourth channel — alpha, or opacity — as two more hex digits: #RRGGBBAA. That ordering, alpha last, is the CSS Color Module Level 4 convention and what this tool produces.
It is not universal. Android's color resources use #AARRGGBB — alpha first. Pasting an 8-digit color between a web CSS file and an Android XML resource without noticing the different channel order silently swaps which end carries transparency, and the result is either a fully opaque color where you expected translucency or the reverse. Worth checking explicitly any time a color value crosses that particular boundary.
RGBA and HSLA notation avoid the ambiguity entirely by naming the channel — rgba(20, 20, 20, 0.5), hsla(0, 0%, 8%, 0.5) — which is one reason to prefer them over 8-digit hex when a color is being generated or read by more than one system.
Lightness isn't brightness
HSL's Lightness is a geometric property of the color-wheel model, not a measurement of how bright the color actually looks to a human eye. Pure yellow and pure blue can share the same Lightness value and look nowhere near equally bright, because the eye is far more sensitive to yellow-green light than to blue — HSL's coordinate system doesn't know that and doesn't try to.
This is exactly the gap that newer CSS color spaces like OKLCH are designed to close — they're built from perceptual research so that equal steps in their lightness axis correspond to equal steps in how bright a color actually looks, which plain HSL was never designed to guarantee. Worth knowing this limitation exists even when HSL is the right practical choice for a given task.
Contrast is computed from luminance, not from Lightness
A common mistake: assuming two colors with very different HSL Lightness values must have good contrast against each other. WCAG's contrast ratio is computed from relative luminance — a weighted, gamma-corrected combination of the red, green and blue channels that accounts for how much each contributes to perceived brightness — not from HSL's L value, and the two can disagree by enough to matter.
The practical thresholds worth keeping in mind: WCAG AA asks for a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text. Neither of those is something you can eyeball correctly from Lightness alone — they need an actual contrast calculation, not a glance at the HSL values.
What this tool doesn't parse, and why that's worth knowing
CSS also defines 147 named colors — keywords like rebeccapurple and cornflowerblue — which this converter doesn't accept as input; it understands hex, rgb()/rgba(), and hsl()/hsla() syntax, not the keyword list. Named colors are a fixed, historically-accumulated vocabulary rather than a systematic notation, so there's no conversion math to do with them the way there is between the three numeric formats — you either recognise the keyword or you look it up.
Round-tripping loses a little precision, and that's normal
Converting RGB to HSL and back does not always return the exact byte values you started with. RGB channels are integers 0–255; HSL's Hue, Saturation and Lightness are conventionally rounded to whole degrees and whole percentage points for display. That rounding is real information loss — converting rgb(53, 89, 141) to HSL and back can land one unit off on a channel from where it started, because the intermediate HSL values were rounded to numbers a human can read and type back in.
This is normal and essentially never visible — a difference of 1 in a 0–255 channel is far below what the eye can distinguish — but it's worth knowing the round-trip isn't bit-exact if you're ever comparing colors programmatically rather than by eye, say in a visual-regression test that diffs exact pixel values after a color has been stored or transmitted in HSL form somewhere along the way.
Where each format actually shows up
- HEX dominates in CSS source, design-tool exports (Figma, Sketch) and anywhere compactness matters — six or eight characters, no function syntax.
- RGB(A) is what Canvas and WebGL APIs generally want, and it's the natural choice anywhere channels need to be manipulated independently in code.
- HSL(A) shows up most in design systems and theming — generating a palette by walking Lightness or Saturation across a fixed Hue, or building light/dark theme variants from one base color, is a natural fit for a coordinate system built around exactly those edits.
Last updated 21 August 2026