Color Models for Web Development

Same colors, different notations. Pick the right one for the job and your code stays readable.

RGB (Red, Green, Blue)

The foundation of digital color. Every color is a mix of red, green, and blue light.

Syntax

/* Functional notation */
color: rgb(255, 0, 0);        /* Red */
color: rgb(0, 255, 0);        /* Green */
color: rgb(0, 0, 255);        /* Blue */
color: rgb(255, 255, 255);    /* White */
color: rgb(0, 0, 0);          /* Black */

/* With alpha (transparency) */
color: rgba(255, 0, 0, 0.5);  /* 50% transparent red */
color: rgb(255 0 0 / 50%);    /* Modern syntax */

How It Works

Each channel ranges from 0 to 255 (8 bits, 256 values per channel).

Red:   0 -------------------- 255
Green: 0 -------------------- 255   16.7 million possible colors
Blue:  0 -------------------- 255

Common RGB Values

ColorRGB
Blackrgb(0, 0, 0)
Whitergb(255, 255, 255)
Redrgb(255, 0, 0)
Greenrgb(0, 255, 0)
Bluergb(0, 0, 255)
Yellowrgb(255, 255, 0)
Cyanrgb(0, 255, 255)
Magentargb(255, 0, 255)
Grayrgb(128, 128, 128)

When to Use RGB

  • When working with code that outputs RGB
  • When you need precise control over individual channels
  • For programmatic color manipulation

Drawbacks

RGB is not intuitive. Quick: what color is rgb(147, 112, 219)? Hard to picture. (It is a medium purple.)

HEX (Hexadecimal)

HEX is RGB written in base-16. Same colors, different notation.

Syntax

color: #FF0000;    /* Red */
color: #00FF00;    /* Green */
color: #0000FF;    /* Blue */
color: #FFFFFF;    /* White */
color: #000000;    /* Black */

/* Shorthand (when each pair is identical) */
color: #F00;       /* Same as #FF0000 */
color: #0F0;       /* Same as #00FF00 */
color: #FFF;       /* Same as #FFFFFF */

/* With alpha (8-digit hex) */
color: #FF000080;  /* 50% transparent red */

Reading HEX Values

#FF5733
 ││││││
 ││││└┴── Blue:  0x33 = 51
 ││└┴──── Green: 0x57 = 87
 └┴────── Red:   0xFF = 255

Hexadecimal digits: 0 1 2 3 4 5 6 7 8 9 A B C D E F

Quick conversions:

  • 00 = 0
  • 80 = 128 (halfway)
  • FF = 255

When to Use HEX

  • The default format in design tools and codebases
  • Compact
  • Easy to copy and paste from design tools
  • Good for color constants

Drawbacks

Same problem as RGB. Not intuitive for manipulation. What color is 20% lighter than #3498db? You cannot tell by looking.

HSL (Hue, Saturation, Lightness)

The most intuitive model for designers and developers. It maps directly to how you think about color.

Syntax

color: hsl(0, 100%, 50%);      /* Red */
color: hsl(120, 100%, 50%);    /* Green */
color: hsl(240, 100%, 50%);    /* Blue */

/* With alpha */
color: hsla(0, 100%, 50%, 0.5);  /* 50% transparent red */
color: hsl(0 100% 50% / 50%);    /* Modern syntax */

The Three Components

Hue (0 to 360): position on the color wheel.

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

Saturation (0% to 100%): intensity of the color.

0%   = Gray (no color)
50%  = Muted
100% = Vivid, pure color

Lightness (0% to 100%): light to dark.

0%   = Black
50%  = Pure hue
100% = White

Visual Representation

Saturation ->
100% ┌────────────────────┐
     │ Vivid              │
     │                    │
 50% │ Muted              │   ^
     │                    │   Lightness
  0% │ Gray───────────────│
     └────────────────────┘
      0%      50%      100%

Creating Color Variations with HSL

This is where HSL pays off:

:root {
  /* Base color */
  --primary: hsl(220, 90%, 50%);

  /* Lighter: bump lightness */
  --primary-light: hsl(220, 90%, 70%);

  /* Darker: drop lightness */
  --primary-dark: hsl(220, 90%, 30%);

  /* Muted: drop saturation */
  --primary-muted: hsl(220, 40%, 50%);

  /* Hover: slightly darker */
  --primary-hover: hsl(220, 90%, 45%);
}

When to Use HSL

  • Color manipulation: tints, shades, hover states
  • Color scales: consistent lightness or saturation steps
  • Design systems: predictable relationships between colors
  • Dark mode: easy to flip lightness values
  • Accessibility: quick contrast adjustments

HSL is Best for CSS Custom Properties

:root {
  --hue-primary: 220;
  --hue-success: 142;
  --hue-warning: 38;
  --hue-error: 0;
}

.button-primary {
  background: hsl(var(--hue-primary), 90%, 50%);
}

.button-primary:hover {
  background: hsl(var(--hue-primary), 90%, 45%);
}

.text-primary-light {
  color: hsl(var(--hue-primary), 70%, 70%);
}

HSB/HSV (Hue, Saturation, Brightness/Value)

Used by design tools (Photoshop, Figma) but not directly supported in CSS.

How It Differs from HSL

HSL Lightness:           HSB Brightness:
100% = White             100% = Full color
50%  = Full color        50%  = Darker
0%   = Black             0%   = Black

In HSB:

  • Brightness 100% + Saturation 100% = vivid color
  • Brightness 100% + Saturation 0% = white

If your design tool gives you HSB, convert to HSL or RGB before pasting into CSS.

Comparison Table

ModelFormatIntuitive?CSS SupportBest For
RGBrgb(255, 128, 0)NoYesProgrammatic manipulation
HEX#FF8000NoYesConstants, copy/paste
HSLhsl(30, 100%, 50%)YesYesDesign work, variations
HSBhsb(30, 100%, 100%)YesNoDesign tools only

Converting Between Models

In JavaScript

// 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;
}

// RGB to 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: h * 360, s: s * 100, l: l * 100 };
}

In Browser DevTools

Most browser DevTools let you click a color value and cycle through formats (Shift+Click on the color swatch in Chrome or Firefox).

Modern CSS: OKLCH and LCH

Newer color spaces that are more perceptually uniform. Equal steps in the values produce equal perceived differences.

/* LCH: Lightness, Chroma, Hue */
color: lch(50% 100 270);

/* OKLCH: improved version */
color: oklch(60% 0.15 250);

Browser support is now wide enough for production work as of 2026. They are better for:

  • Perceptually even color scales
  • Consistent perceived contrast across hues
  • Wider color gamut displays (P3, Rec2020)

HSL still handles most everyday needs. Reach for OKLCH when scales feel uneven across hues.

Practical Recommendations

  1. Store colors as HEX in design tokens and constants.
  2. Use HSL in CSS when you need variations.
  3. Use RGB in JavaScript for color math.
  4. Compose CSS custom properties from HSL parts for theming.
:root {
  /* Define base colors */
  --color-primary-h: 220;
  --color-primary-s: 90%;
  --color-primary-l: 50%;

  /* Compose full color */
  --color-primary: hsl(
    var(--color-primary-h),
    var(--color-primary-s),
    var(--color-primary-l)
  );

  /* Easy variations */
  --color-primary-light: hsl(
    var(--color-primary-h),
    var(--color-primary-s),
    70%
  );
}

Summary

ModelRemember
RGB0 to 255 per channel, foundation of digital color
HEXRGB in base-16, most common format in tools
HSLHue (0 to 360), Saturation (0 to 100%), Lightness (0 to 100%). Use this.
HSBDesign tools use it. Convert to HSL for CSS.

Next: 03-color-wheel.md covers how colors relate on the wheel.