HEX, RGB, and HSL: Understanding Color Formats for the Web

A practical guide to web color formats — what HEX, RGB, and HSL mean, when to use each, and how to convert between them.

Colors on the web can be written in at least half a dozen ways, but three formats dominate: HEX, RGB, and HSL. Every front-end developer learns all three eventually, and every designer has a preference. Understanding what each format actually represents — not just how to write it — makes color work much faster and less error-prone.

HEX: The Old Faithful

HEX colors look like #FF5733 or #3B82F6. The # prefix marks it as hexadecimal, and the six characters that follow encode the red, green, and blue components, two hex digits each.

#FF5733
  ^^     Red:   FF = 255
    ^^   Green: 57 = 87
      ^^ Blue:  33 = 51

Hexadecimal counts from 0-9 then A-F, so each digit goes 0–15. Two hex digits give you 0–255 — the same range as a single byte. This is why colors max out at 255: it's the largest value that fits in one byte.

Shorthand HEX works when both digits in each pair are identical. #FFCC00 can be written as #FC0, and #AABBCC as #ABC. The browser expands each digit by doubling it: FFF, CCC.

HEX with alpha (transparency) adds two more digits at the end: #FF573380 — the 80 is roughly 50% opacity in hex. This is less common than rgba() for transparency, partly because doing the hex-to-percentage math in your head is annoying.

HEX is the most compact format and the most common in design tools, CSS codebases, and color palettes. Its weakness: it's hard to read at a glance. #3B82F6 tells you nothing intuitively — you need to parse it.

RGB: Explicit and Readable

RGB spells out what HEX encodes: red, green, and blue as decimal numbers from 0 to 255.

color: rgb(255, 87, 51);    /* same as #FF5733 */
color: rgba(255, 87, 51, 0.5);  /* 50% transparent */

The values map directly to light intensity. rgb(255, 0, 0) is pure red — full red channel, zero green, zero blue. rgb(0, 0, 0) is black (no light). rgb(255, 255, 255) is white (all channels full).

RGBA adds an alpha channel as a decimal from 0 (invisible) to 1 (fully opaque). This is the standard way to handle transparency in CSS.

RGB is intuitive if you think in terms of mixing colored lights. It's also what screens actually use — every pixel is a tiny red, green, and blue light source at varying intensities. But for design work, RGB has a usability problem: it's hard to predict what rgb(180, 60, 220) looks like without rendering it. It doesn't map to how humans think about color.

HSL: Designed for Humans

HSL stands for Hue, Saturation, Lightness. It was designed to be intuitive for people who think about color in natural terms.

color: hsl(11, 100%, 60%);   /* same orange-red as #FF5733 */
color: hsla(11, 100%, 60%, 0.5);  /* 50% transparent */

Hue is the color itself, expressed as a degree on a color wheel (0–360):

  • 0° / 360° = Red
  • 60° = Yellow
  • 120° = Green
  • 180° = Cyan
  • 240° = Blue
  • 300° = Magenta

Saturation is how vivid the color is, from 0% (gray) to 100% (fully vivid).

Lightness is how light or dark, from 0% (black) to 100% (white), with 50% being the "pure" color.

The power of HSL becomes clear when you're building a design system. Want a lighter version of your brand blue? Just increase the lightness. Want a muted version? Reduce the saturation. These adjustments are trivial in HSL and opaque in HEX or RGB.

/* A blue at different lightness levels — easy to reason about */
hsl(220, 90%, 20%)   /* very dark blue */
hsl(220, 90%, 40%)   /* dark blue */
hsl(220, 90%, 60%)   /* medium blue */
hsl(220, 90%, 80%)   /* light blue */
hsl(220, 90%, 95%)   /* very light blue / almost white */

Try doing that intuitively with HEX values.

Converting Between Formats

The math behind conversion is worth understanding even if you always use a tool.

HEX → RGB is straightforward: convert each pair of hex digits to decimal. #FF5733(255, 87, 51).

RGB → HEX is the reverse: convert each decimal to two hex digits. (59, 130, 246)3B82F6#3B82F6.

RGB → HSL is more involved. The algorithm:

  1. Normalize R, G, B to 0–1 range (divide by 255)
  2. Find the maximum and minimum of the three values
  3. Lightness = (max + min) / 2
  4. If max == min, saturation = 0 (it's gray)
  5. Otherwise, saturation depends on whether lightness is above or below 0.5
  6. Hue depends on which channel is the maximum

Nobody does this by hand. That's what color converter tools are for.

When to Use Each Format

Use HEX when:

  • Writing CSS that will be read by other developers (it's the convention)
  • Copying colors from Figma, Sketch, or any design tool (they export HEX by default)
  • Storing colors in a database or config file

Use RGB / RGBA when:

  • You need transparency (rgba is cleaner than 8-digit hex)
  • Working in JavaScript to manipulate color values programmatically
  • Passing colors to canvas or WebGL contexts

Use HSL / HSLA when:

  • Building a design system with color scales
  • Generating color variants programmatically (hover states, disabled states)
  • You want human-readable color definitions in your CSS variables

Many modern design systems define their palette in HSL and derive all variants from a single hue value:

:root {
  --brand-hue: 220;
  --brand-color: hsl(var(--brand-hue), 90%, 55%);
  --brand-light: hsl(var(--brand-hue), 90%, 85%);
  --brand-dark: hsl(var(--brand-hue), 90%, 30%);
}

Change --brand-hue and the whole palette shifts. That's impossible with hardcoded HEX values.

The New CSS Color Formats

Modern CSS has expanded beyond the classic three. A few worth knowing:

oklch() — A perceptually uniform color space where equal numeric changes produce equal perceived differences. Increasingly popular for design systems that need predictable color scales. Supported in all modern browsers as of 2023.

color-mix() — Mix two colors directly in CSS: color-mix(in srgb, #FF5733 40%, white). Useful for generating tints without JavaScript.

color(display-p3 ...) — Access the wider P3 color gamut available on modern displays (iPhone, Mac with ProMotion). Enables more vivid colors than standard sRGB.

For most production work, HEX, RGB, and HSL still cover 95% of use cases. But if you're building a new design system today, oklch() is worth considering.


To convert between HEX, RGB, and HSL without doing the math manually, use the Color Converter tool — paste any format and get the other two instantly.