Color Spaces Explained: RGB, HSL, HEX, and HSB for Developers

Understand the differences between color spaces, when to use each format, and how to convert between RGB, HSL, HEX, and HSB in CSS and JavaScript.

By Belqassim Djafer · Published · Updated

Why Color Formats Matter

Web developers regularly deal with three main color formats: HEX (#3498db), RGB (rgb(52, 152, 219)), and HSL (hsl(207, 69%, 53%)). Choosing the right format for the right context makes your code more readable and your design work more intuitive.

HEX Colors

Hexadecimal color notation expresses RGB values in base-16:

#3498db     /* Full 6-digit hex */
#34a         /* Shorthand for #3344aa */
#3498dbff   /* 8-digit hex with alpha channel */
  • Range: 00–FF per channel (0–255 in decimal)
  • Best for: Sharing colors with designers, CSS variables, copy-pasting from design tools
  • Drawback: Not intuitive to edit manually — hard to visualise what #7f3f9f looks like

HEX is the most common format in CSS because it's compact and widely supported. Figma, Sketch, and most design tools default to HEX.

RGB — Red, Green, Blue

RGB models colors as mixtures of red, green, and blue light:

color: rgb(52, 152, 219);    /* Each channel: 0–255 */
color: rgba(52, 152, 219, 0.8);  /* With opacity 0–1 */
color: rgb(52 152 219 / 0.8);    /* Modern space-separated syntax */
  • Range: 0–255 per channel
  • Best for: Programmatic color manipulation, Canvas API, reading from design specs
  • Drawback: Adjusting brightness or saturation requires changing all three values simultaneously

RGB in JavaScript

// Convert HEX to RGB
function hexToRgb(hex) {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result ? {
    r: parseInt(result[1], 16),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

// Convert RGB to HEX
function rgbToHex(r, g, b) {
  return "#" + [r, g, b].map(v => v.toString(16).padStart(2, "0")).join("");
}

HSL — Hue, Saturation, Lightness

HSL maps colors to a cylinder based on how humans perceive color:

color: hsl(207, 69%, 53%);        /* Hue: 0-360, Saturation/Lightness: 0-100% */
color: hsla(207, 69%, 53%, 0.8);  /* With alpha */
color: hsl(207 69% 53% / 0.8);    /* Modern syntax */
  • Hue: 0°–360° around the color wheel (0/360=red, 120=green, 240=blue)
  • Saturation: 0% = grey, 100% = full color
  • Lightness: 0% = black, 50% = normal color, 100% = white
  • Best for: Creating color palettes, building theming systems, programmatic adjustments

HSL is much more intuitive than RGB for design work. To make a color 20% lighter, you increase L by 20. To create a muted variant, you decrease S.

Building a Color Palette with HSL

:root {
  --brand-hue: 207;
  --brand-saturation: 69%;
  
  --color-100: hsl(var(--brand-hue) var(--brand-saturation) 90%);
  --color-200: hsl(var(--brand-hue) var(--brand-saturation) 80%);
  --color-300: hsl(var(--brand-hue) var(--brand-saturation) 70%);
  --color-400: hsl(var(--brand-hue) var(--brand-saturation) 60%);
  --color-500: hsl(var(--brand-hue) var(--brand-saturation) 53%); /* base */
  --color-600: hsl(var(--brand-hue) var(--brand-saturation) 43%);
  --color-700: hsl(var(--brand-hue) var(--brand-saturation) 33%);
  --color-800: hsl(var(--brand-hue) var(--brand-saturation) 23%);
  --color-900: hsl(var(--brand-hue) var(--brand-saturation) 13%);
}

Changing a single CSS variable (--brand-hue) recolors the entire design.

HSB/HSV — Hue, Saturation, Brightness/Value

HSB (also called HSV) is similar to HSL but uses brightness instead of lightness:

  • B/V: 0% = black, 100% = full-brightness color (not white like HSL)
  • HSB is used in Photoshop, Figma colour pickers, and most design software
  • HSL is used in CSS and the web platform
HSL(120, 100%, 50%) = pure green
HSB(120, 100%, 100%) = pure green
HSL(120, 100%, 100%) = white (L=100% is always white)
HSB(120, 100%, 50%) = dark green (V=50%)

OKLCH — The Modern Choice for 2025+

CSS now supports OKLCH, a perceptually uniform color space:

color: oklch(60% 0.15 220);  /* Lightness Chroma Hue */

Why OKLCH is better for design systems:

  • Perceptually uniform: step changes in L produce equal perceived changes in brightness
  • Wider gamut than sRGB (supports P3 colors on modern displays)
  • Easier to build accessible color palettes that maintain contrast ratios
/* Equal perceived brightness steps in OKLCH */
--gray-100: oklch(98% 0 0);
--gray-500: oklch(55% 0 0);
--gray-900: oklch(20% 0 0);

Color Contrast and Accessibility

WCAG 2.1 requires minimum contrast ratios:

  • AA (body text): 4.5:1
  • AA (large text): 3:1
  • AAA: 7:1
// Calculate relative luminance (simplified)
function luminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(v => {
    v /= 255;
    return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
  });
  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}

function contrast(rgb1, rgb2) {
  const l1 = luminance(...rgb1);
  const l2 = luminance(...rgb2);
  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);
  return (lighter + 0.05) / (darker + 0.05);
}

Quick Reference: When to Use Each Format

Format Use Case
HEX CSS variables, design handoff, static colors
RGB/RGBA Canvas drawing, image processing, alpha blending
HSL Dynamic theming, color palettes, design systems
HSB Reading values from design tools (Figma, Photoshop)
OKLCH New projects, wide-gamut displays, accessible palettes

Use our Color Converter to instantly convert between all these formats and explore color values visually.

Conclusion

Understanding color spaces turns color from magic strings into a predictable design tool. Use HEX for static values, HSL for dynamic theming, and OKLCH for future-proof design systems. When in doubt, use HSL for any color you need to programmatically adjust — its hue-saturation-lightness model directly maps to how designers think about color.

Related Tools