TC
design6 min read

Understanding Color Formats: HEX, RGB & HSL

Every color you see on a screen is built from the same three ingredients: red, green, and blue light. Yet designers and developers refer to colors in at least three different notations — #FF3366, rgb(255, 51, 102), and hsl(345, 100%, 60%). They all describe the exact same pink. So why do we need three formats, and when should you reach for each one?


How screens create color

Screens work by additive color mixing. Each pixel contains a tiny red, green, and blue sub-pixel. When all three fire at full power, you see white. When none fire, you see black. Everything in between is a blend of those three channels at different intensities.

This is the opposite of how paint works. Mix red, yellow, and blue paint and you get a muddy brown — that's subtractive mixing, where pigments absorb light. Screens emit light, so more color means brighter, not darker.

Fun fact: Your eye has three types of cone cells, roughly sensitive to red, green, and blue wavelengths. RGB isn't an arbitrary choice — it maps directly to human biology.

RGB: the machine's native tongue

RGB stands for Red, Green, Blue. Each channel is a number from 0 to 255, representing how much of that color to emit. Zero means off, 255 means full blast.

rgb(255, 0, 0)    → pure red
rgb(0, 255, 0)    → pure green
rgb(0, 0, 255)    → pure blue
rgb(255, 255, 0)  → yellow (red + green)
rgb(0, 0, 0)      → black (nothing on)
rgb(255, 255, 255) → white (everything on)

Why 0–255?

Each channel gets 8 bits of data (one byte). 28 = 256 possible values, giving us the 0–255 range. Three channels means 24 bits total, which produces 16.7 million possible colors — more than enough to look continuous to the human eye.

RGB is what the hardware understands. Your GPU, your monitor, your camera sensor — they all speak RGB. When you write rgb(255, 51, 102) in CSS, you're essentially giving the pixel direct instructions.

When to use RGB

  • When you need precise channel control (e.g. blending, masking, shader code)
  • When working with APIs or libraries that accept RGB tuples
  • When doing programmatic color math (adding, averaging, interpolating channels)

HEX: RGB in disguise

HEX color codes are not a different color system — they're just RGB written in base 16 (hexadecimal) instead of base 10. The six characters after the # are three pairs, each representing one RGB channel.

#FF3366
 ││││││
 ││││└┘ Blue:  66 hex = 102 decimal
 ││└┘   Green: 33 hex =  51 decimal
 └┘     Red:   FF hex = 255 decimal

So #FF3366 = rgb(255, 51, 102)

Why hexadecimal?

Hex is more compact. #FF3366 is shorter than rgb(255, 51, 102). In the early web, every byte mattered — HTML files were hand-typed over dial-up connections. HEX became the standard for CSS colors simply because it was terse and unambiguous.

Shorthand notation

When both digits in each pair are the same, you can shorten to three characters. #FF3366 becomes #F36. The browser expands each digit by doubling it: F→FF, 3→33, 6→66.

When to use HEX

  • In CSS stylesheets (the most common convention)
  • In design tools like Figma or Photoshop (the default color input)
  • When sharing colors in text — #FF3366 is universally understood

HSL: the human-friendly format

RGB and HEX are great for machines, but terrible for humans. Quick: is rgb(51, 102, 255) a warm or cool color? Hard to tell at a glance. That's where HSL comes in.

HSL stands for Hue, Saturation, Lightness. It describes color the way people actually think about it:

  1. Hue (0–360) — The position on the color wheel. 0 is red, 120 is green, 240 is blue, and 360 wraps back to red.
  2. Saturation (0–100%) — How vivid the color is. 0% is completely grey, 100% is the purest version of that hue.
  3. Lightness (0–100%) — How light or dark. 0% is always black, 100% is always white, and 50% gives you the most vibrant version.
hsl(345, 100%, 60%)  → vivid pink
hsl(345, 100%, 80%)  → lighter pink (same hue, more light)
hsl(345, 30%, 60%)   → muted pink (same hue, less saturation)
hsl(200, 100%, 60%)  → vivid blue (different hue, same formula)
The killer feature of HSL: You can create entire color palettes by keeping saturation and lightness constant and just rotating the hue. Need a set of five harmonious colors? Pick hues 72 degrees apart (360 / 5 = 72) and you get an evenly-spaced palette.

When to use HSL

  • When building color palettes or design systems programmatically
  • When you need to make a color “lighter” or “more muted” — just adjust L or S
  • When checking accessibility contrast — lightness differences are easy to reason about
  • In CSS custom properties where you want to tweak shades with calc()

Side-by-side comparison

Here's how the same set of colors looks in all three formats:

ColorHEXRGBHSL
#FF3366
#FF3366255, 51, 102345, 100%, 60%
#FFD600
#FFD600255, 214, 050, 100%, 50%
#0055FF
#0055FF0, 85, 255220, 100%, 50%
#00CC66
#00CC660, 204, 102150, 100%, 40%
#1A1A1A
#1A1A1A26, 26, 260, 0%, 10%

Which format should you use?

There is no single “best” format. Each one fits a different context:

  • Use HEX as your default in CSS and design files. It's the most widely recognized and compact.
  • Use RGB when doing math with colors — blending, opacity calculations, or passing values to canvas/WebGL APIs.
  • Use HSL when you need to think about color relationships — building palettes, creating hover states, or adjusting a brand color to lighter and darker variants.

The good news is that converting between them is instant and lossless. They all describe the same 16.7 million colors — just from different angles. Think of HEX and RGB as the same language with different alphabets, and HSL as a completely different language that maps perfectly to the others.

Knowing all three formats doesn't mean you use all three everywhere. It means you pick the right one for the job — and switch effortlessly when the context changes.

Try it yourself

Put what you learned into practice with our Color Picker.