Color Formats Explained: HEX, RGB, HSL & When to Use Each

Every color on your screen is just numbers. The same shade of blue can be written as #3498db, rgb(52, 152, 219), or hsl(204, 70%, 53%) — different formats expressing the same color. Understanding when to use each format makes your CSS cleaner, your color manipulations easier, and your design system more maintainable.

The Three Main Formats

HEX — Hexadecimal

HEX is the most widely used color format on the web. It represents red, green, and blue channels as two hexadecimal digits each, prefixed with #.

Format:  #RRGGBB  or  #RGB (shorthand)
Range:   00–FF per channel (0–255 in decimal)

Examples:
  #ff0000    → Pure red
  #00ff00    → Pure green
  #0000ff    → Pure blue
  #ffffff    → White
  #000000    → Black
  #3498db    → A nice blue

Shorthand (when both digits match):
  #fff       → #ffffff (white)
  #f00       → #ff0000 (red)
  #369       → #336699

HEX with Alpha

#RRGGBBAA  or  #RGBA

Examples:
  #3498db80  → Blue at 50% opacity (80 hex ≈ 128 ≈ 50%)
  #00000033  → Black at 20% opacity
  #ff000000  → Fully transparent red
💡 Hex Opacity Reference: FF = 100%, BF = 75%, 80 = 50%, 40 = 25%, 00 = 0%. A quick formula: multiply the desired percentage by 255, then convert to hex.

RGB — Red, Green, Blue

RGB defines color using decimal values (0–255) for each channel. It's more readable than HEX and supports alpha transparency natively.

Format:  rgb(red, green, blue)
         rgba(red, green, blue, alpha)

Range:   0–255 per channel, 0–1 for alpha

Examples:
  rgb(255, 0, 0)        → Pure red
  rgb(52, 152, 219)     → The same blue as #3498db
  rgba(0, 0, 0, 0.5)    → Black at 50% opacity

Modern CSS (Level 4):
  rgb(52 152 219)              → Spaces instead of commas
  rgb(52 152 219 / 0.5)       → Alpha with slash syntax
  rgb(52 152 219 / 50%)       → Alpha as percentage

HSL — Hue, Saturation, Lightness

HSL is the most intuitive format for humans. Instead of mixing red, green, and blue light, you describe a color by its position on the color wheel, how vivid it is, and how bright it is.

Format:  hsl(hue, saturation, lightness)
         hsla(hue, saturation, lightness, alpha)

Ranges:
  Hue:         0–360 (degrees on the color wheel)
  Saturation:  0%–100% (0% = gray, 100% = full color)
  Lightness:   0%–100% (0% = black, 50% = pure color, 100% = white)

Examples:
  hsl(0, 100%, 50%)     → Pure red
  hsl(120, 100%, 50%)   → Pure green
  hsl(240, 100%, 50%)   → Pure blue
  hsl(204, 70%, 53%)    → The same blue as #3498db

The Color Wheel:
    0° / 360°  → Red
   60°         → Yellow
  120°         → Green
  180°         → Cyan
  240°         → Blue
  300°         → Magenta
💡 Why HSL Is Powerful: Need a darker version of a color? Just reduce lightness. Need a muted version? Reduce saturation. Need complementary color? Add 180° to hue. HSL makes color manipulation intuitive without math.

When to Use Which Format

Use HEX When:

  • Copying colors from design tools — Figma, Sketch, and Photoshop default to HEX.
  • Writing one-off color values — Compact and universally recognized.
  • Matching brand guidelines — Brand colors are almost always specified in HEX.
  • Working with legacy CSS — HEX has the broadest browser support history.

Use RGB When:

  • You need alpha transparencyrgba() was the standard way to add opacity before HSL/HEX8 support.
  • Programmatic color generation — Pixel manipulation APIs (Canvas, WebGL) use RGB natively.
  • Interpolating between colors — RGB interpolation is straightforward mathematically.

Use HSL When:

  • Building a design system — Define a base hue, then create variations by adjusting saturation and lightness.
  • Creating color palettes — Generate harmonious palettes using hue relationships (complementary, triadic, analogous).
  • Dynamic themes — CSS custom properties with HSL make dark mode trivial.
  • Accessibility adjustments — Easy to check and adjust contrast by modifying lightness.

Building a Color System with HSL

HSL shines when you need to create a consistent palette from a single base color:

:root {
  /* Base color: a blue at hue 204° */
  --color-primary-h: 204;
  --color-primary-s: 70%;

  /* Generate a full palette by varying lightness */
  --color-primary-50:  hsl(var(--color-primary-h), var(--color-primary-s), 95%);
  --color-primary-100: hsl(var(--color-primary-h), var(--color-primary-s), 90%);
  --color-primary-200: hsl(var(--color-primary-h), var(--color-primary-s), 80%);
  --color-primary-300: hsl(var(--color-primary-h), var(--color-primary-s), 70%);
  --color-primary-400: hsl(var(--color-primary-h), var(--color-primary-s), 60%);
  --color-primary-500: hsl(var(--color-primary-h), var(--color-primary-s), 53%);  /* Base */
  --color-primary-600: hsl(var(--color-primary-h), var(--color-primary-s), 43%);
  --color-primary-700: hsl(var(--color-primary-h), var(--color-primary-s), 33%);
  --color-primary-800: hsl(var(--color-primary-h), var(--color-primary-s), 23%);
  --color-primary-900: hsl(var(--color-primary-h), var(--color-primary-s), 13%);
}

/* Dark mode — just adjust the lightness values */
@media (prefers-color-scheme: dark) {
  :root {
    --color-primary-500: hsl(var(--color-primary-h), var(--color-primary-s), 65%);
  }
}

Converting Between Formats

HEX → RGB

// Parse hex string to RGB values
function hexToRgb(hex) {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return { r, g, b };
}

hexToRgb('#3498db');  // { r: 52, g: 152, b: 219 }

RGB → HSL

function rgbToHsl(r, g, b) {
  r /= 255; g /= 255; b /= 255;
  const max = Math.max(r, g, b), min = Math.min(r, g, b);
  let h, s, l = (max + min) / 2;

  if (max === min) {
    h = s = 0;
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
      case g: h = ((b - r) / d + 2) / 6; break;
      case b: h = ((r - g) / d + 4) / 6; break;
    }
  }
  return {
    h: Math.round(h * 360),
    s: Math.round(s * 100),
    l: Math.round(l * 100)
  };
}

rgbToHsl(52, 152, 219);  // { h: 204, s: 70, l: 53 }

CSS Named Colors

CSS defines 148 named colors. Some useful ones beyond the basics:

Color Name          HEX         RGB
------------------  ---------   -------------------
cornflowerblue      #6495ED     rgb(100, 149, 237)
darkcyan            #008B8B     rgb(0, 139, 139)
slategray           #708090     rgb(112, 128, 144)
tomato              #FF6347     rgb(255, 99, 71)
mediumpurple        #9370DB     rgb(147, 112, 219)
coral               #FF7F50     rgb(255, 127, 80)
steelblue           #4682B4     rgb(70, 130, 180)
darkslategray       #2F4F4F     rgb(47, 79, 79)
⚠️ Accessibility Tip: When choosing text and background colors, ensure a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text (WCAG AA). HSL makes this easier — a lightness difference of ~40–50% between text and background usually meets the requirement.

Modern CSS Color Functions

CSS Color Level 4 introduces powerful new features:

color-mix()

/* Mix two colors */
background: color-mix(in srgb, #3498db, white 30%);  /* 30% lighter */
background: color-mix(in srgb, #3498db, black 20%);  /* 20% darker */

/* Create a semi-transparent version */
background: color-mix(in srgb, #3498db, transparent 50%);

Relative Color Syntax (coming soon)

/* Derive new colors from existing ones */
--lighter: hsl(from var(--primary) h s calc(l + 20%));
--desaturated: hsl(from var(--primary) h calc(s - 30%) l);
--complementary: hsl(from var(--primary) calc(h + 180) s l);

Quick Reference

Format    Example              Best For
--------  -------------------  --------------------------------
HEX       #3498db              Design specs, brand colors
HEX8      #3498db80            HEX with transparency
RGB       rgb(52, 152, 219)    Programmatic colors, Canvas
RGBA      rgba(52,152,219,.5)  RGB with transparency
HSL       hsl(204, 70%, 53%)   Color systems, palettes
HSLA      hsla(204,70%,53%,.5) HSL with transparency
Named     cornflowerblue       Quick prototyping

Need to convert colors between formats?

Open Color Converter →