HEX, RGB, and HSL: how to convert colors between formats and when to use each
The same color can be written as #1E90FF, rgb(30, 144, 255), or hsl(210, 100%, 56%), and CSS accepts all three. Converting between them by hand is mostly arithmetic, but it is arithmetic worth understanding, because each format is good at a different job. The Color Converter & Contrast Checker does the conversion live in your browser with a swatch and a WCAG contrast check, and nothing you paste ever leaves the page.
What each format actually says
RGB is the native language of screens: three channels, red, green, and blue, each from 0 to 255, mixed as light. rgb(30, 144, 255) means a little red, a fair amount of green, and full blue.
HEX is the same three RGB channels written in base 16. Each channel becomes a two digit hex value, so 30 is 1E, 144 is 90, and 255 is FF, giving #1E90FF. HEX carries no extra information over RGB; it is just a compact spelling of it.
HSL describes the color the way a person would: hue is the position on the color wheel from 0 to 360 degrees (0 is red, 120 is green, 240 is blue), saturation is how vivid it is from grey to pure, and lightness runs from black through the full color to white. This is why designers tend to prefer it. Want a darker shade of your brand blue? Lower the lightness and leave hue and saturation alone. In RGB you would have to adjust all three channels in the right proportions to get the same result.
How the conversions work
HEX to RGB is direct: split the six digits into three pairs and read each pair as a base 16 number. RGB to HEX is the reverse.
RGB to HSL takes a little more. Lightness is the average of the largest and smallest channel. Saturation measures how far apart those extremes are, scaled by the lightness. Hue depends on which channel dominates: if blue is largest, the color sits in the blue region of the wheel, nudged toward red or green by the other two channels. Going from HSL back to RGB reverses the process. None of this needs memorizing; the point is that HSL is a reshaping of the same information, not a different color space with a different gamut.
One color, three spellings
| Format | Value |
|---|---|
| HEX | #1E90FF |
| RGB | rgb(30, 144, 255) |
| HSL | hsl(210, 100%, 56%) |
Adding alpha
All three formats can carry transparency. HEX grows to eight digits, with the last pair as the alpha channel: #1E90FF80 is the same blue at roughly 50 percent opacity, since 80 in hex is 128 out of 255. RGB and HSL add a fourth value between 0 and 1: rgba(30, 144, 255, 0.5) and hsla(210, 100%, 56%, 0.5). Modern CSS also accepts the slash form, rgb(30 144 255 / 0.5), which means the same thing.
Which one to reach for
- HEX for storing and sharing exact values: design tokens, config files, copy and paste between tools. Compact and unambiguous.
- RGB when code manipulates channels directly, or when you are matching a value from a canvas or image pixel.
- HSL when you are designing: building a palette of tints and shades from one hue, or nudging a color lighter to pass WCAG color contrast requirements without drifting its hue.
Gotchas
- Three digit shorthand.
#F80is legal HEX and expands by doubling each digit, so it means#FF8800, not#0F0800or anything with leading zeros. - Percentages in HSL. Saturation and lightness are percentages and need the
%sign in CSS.hsl(210, 100, 56)is invalid;hsl(210, 100%, 56%)is what you meant. Hue takes no unit. - Rounding on round trips. RGB channels are integers, HSL values are usually rounded to whole percents, so converting HEX to HSL and back can land one step away from where you started,
#1E90FFbecoming#1F90FF, for example. Harmless visually, but it can produce noisy diffs in a token file. Keep one format as the source of truth and derive the others from it.
Paste any of these forms into the Color Converter & Contrast Checker and it shows the other two, a live swatch, and whether the color passes AA and AAA contrast against a background.