HEX, RGB and HSL Color Codes Explained (With Conversions)
What HEX, RGB and HSL color codes mean, how to read them, how to convert between them by hand, and which one to use in CSS, with worked examples throughout.
Updated
HEX, RGB and HSL are three ways of writing the same color. HEX and RGB both describe how much red, green and blue light to mix, written in base 16 or base 10. HSL describes the color the way people think about it, as a hue, a saturation and a lightness. The orange #ff6600, rgb(255, 102, 0) and hsl(24, 100%, 50%) are one color in three notations.
RGB: three channels of light
Screens make color by lighting red, green and blue sub-pixels at different intensities. RGB writes those three intensities on a scale from 0 (off) to 255 (full). So rgb(255, 0, 0) is pure red, rgb(0, 0, 0) is black, rgb(255, 255, 255) is white, and equal values such as rgb(128, 128, 128) are grey.
Each channel is stored in one byte, which holds 256 values. Three bytes give about 16.7 million combinations, which is where the phrase "16 million colors" comes from.
RGB is what JavaScript returns from getComputedStyle and what canvas APIs work in. It is precise but hard to reason about. Few people can look at rgb(59, 130, 246) and picture a blue, let alone make it slightly lighter.
HEX: the same channels in base 16
A HEX code is RGB written in hexadecimal, with two digits per channel after a #. Hex digits run 0 to 9 then a to f, so 00 is 0 and ff is 255. Reading #ff6600 left to right: red ff is 255, green 66 is 102, blue 00 is 0.
To convert one two-digit pair, multiply the first digit by 16 and add the second. For 66, that is 6 times 16 plus 6, which gives 102. Going the other way, divide by 16: 130 is 8 remainder 2, so it becomes 82. That is how rgb(59, 130, 246) becomes #3b82f6.
A few conventions are worth knowing:
- Case does not matter.
#FF6600and#ff6600are identical. - When both digits of every pair match, you can shorten to three digits.
#ff6600becomes#f60, and#ffffffbecomes#fff. - Eight digits add an alpha channel.
#ff660080is the same orange at roughly 50 percent opacity, since80is 128 out of 255.
HEX is the most compact notation and the default in Figma, Sketch and most brand guidelines. When you want to know what a code is called, the Color Name Finder matches any hex value to the nearest of the 148 CSS named colors, so #ff6600 comes back close to darkorange.
HSL: hue, saturation, lightness
HSL rearranges the same information into three values that map to how we describe color in conversation.
- Hue is a position on the color wheel in degrees.
0is red,120is green,240is blue, and360wraps back to red. Orange sits around24, yellow at60, cyan at180. - Saturation is how vivid the color is, from
0%(grey) to100%(fully saturated). - Lightness runs from
0%(black) through50%(the pure hue) to100%(white).
So hsl(24, 100%, 50%) is #ff6600. The power of HSL is that edits are predictable. Want a hover state slightly darker? Drop lightness to 42%. Want a muted version for a disabled button? Pull saturation down to 30%. Want a complementary color? Add 180 to the hue. Doing any of those in HEX means guessing.
HSL lightness is not perceptual.hsl(60, 100%, 50%)yellow andhsl(240, 100%, 50%)blue share the same lightness value, but the yellow looks far brighter. For contrast and accessibility decisions, use a contrast ratio, not the L in HSL. Newer CSS color spaces such as OKLCH fix this, but HSL remains the most widely supported.
Converting RGB to HSL by hand
Take rgb(255, 102, 0). Divide each channel by 255 to get 1.0, 0.4 and 0.0. Then:
- Lightness is the average of the max and min: (1.0 + 0.0) / 2 =
0.5, or50%. - Saturation is (max - min) / (1 - abs(2L - 1)): 1.0 / 1.0 =
1.0, or100%. - Hue depends on which channel is the max. Red is the max, so hue is 60 times (G - B) / (max - min): 60 times 0.4 =
24degrees.
Result: hsl(24, 100%, 50%). The arithmetic is fiddly when green or blue is the dominant channel, because you add an offset of 120 or 240 degrees. In practice, paste the value into the Color Converter and read all four notations, including HSV, from one screen.
Which notation to use in CSS
All three render the same, so pick by convenience:
- Use HEX for design tokens and anything copied from a design file.
- Use HSL when you build a palette in code, because tints and shades are just lightness changes. A button scale might be
hsl(24, 100%, 35%),45%,50%,60%and90%. - Use RGB when a value comes from JavaScript or when you need to match a legacy stylesheet.
Modern CSS also accepts the space-separated form, rgb(255 102 0 / 50%), where the slash introduces alpha. Both forms work in every current browser.
If you are building a scheme from a single brand color, the Color Palette Generator takes a hex value and returns complementary, analogous, triadic and split-complementary sets with tint and shade scales, exported as CSS variables or a Tailwind config.
The rest of the colors category covers contrast checking, gradients and palette extraction from images.
Try it
Paste #3b82f6 into the Color Converter to see it as rgb(59, 130, 246) and hsl(217, 91%, 60%), then drag the picker and watch all three notations update together.