Skip to main content
Ordinary Utils Fast, free tools that respect your time.

Color Theory for Developers

Understanding HEX, RGB, HSL, and practical color usage in web development.

Design 11 min read Last updated: June 19, 2026

Why Color Matters in Development

Color is fundamental to user interface design. As developers, we constantly work with color values—whether styling components, building design systems, or ensuring accessibility. Understanding color theory and the different color models helps you make better decisions and work more efficiently.

Different color formats have different strengths. Knowing when to use HEX, RGB, or HSL can simplify your code and make color manipulation more intuitive.

RGB: The Foundation

RGB stands for Red, Green, Blue—the three primary colors of light. Screens display colors by mixing these three channels, each ranging from 0 to 255:

rgb(255, 0, 0)    /* Pure red */
rgb(0, 255, 0)    /* Pure green */
rgb(0, 0, 255)    /* Pure blue */
rgb(255, 255, 255) /* White (all channels max) */
rgb(0, 0, 0)       /* Black (all channels off) */
rgb(128, 128, 128) /* Gray (equal values) */

RGBA: Adding Transparency

RGBA adds an alpha channel for transparency, ranging from 0 (fully transparent) to 1 (fully opaque):

rgba(255, 0, 0, 0.5)   /* 50% transparent red */
rgba(0, 0, 0, 0.3)     /* 30% black overlay */
rgba(255, 255, 255, 0) /* Fully transparent */

When to Use RGB

  • When you need transparency (RGBA)
  • When programmatically manipulating individual color channels
  • When working with image processing or canvas APIs

HEX: The Web Standard

HEX (hexadecimal) is the most common color format in web development. It represents RGB values in base-16 notation:

#RRGGBB

#FF0000  /* Red: FF=255, 00=0, 00=0 */
#00FF00  /* Green */
#0000FF  /* Blue */
#FFFFFF  /* White */
#000000  /* Black */

Shorthand HEX

When each pair has identical digits, you can use 3-character shorthand:

#FF0000 → #F00
#FFFFFF → #FFF
#336699 → #369
#112233 → #123

HEX with Alpha

Modern browsers support 8-digit HEX for transparency:

#RRGGBBAA

#FF000080  /* 50% transparent red (80 hex ≈ 128 decimal ≈ 50%) */
#00000033  /* ~20% black overlay */

When to Use HEX

  • Default choice for CSS color values
  • Compact representation for design handoffs
  • When copying colors from design tools like Figma

HSL: Human-Friendly Colors

HSL (Hue, Saturation, Lightness) describes colors in a way that's more intuitive for humans:

Hue (0-360°)

The color itself, represented as a position on the color wheel. 0°=red, 120°=green, 240°=blue.

Saturation (0-100%)

Color intensity. 0%=gray, 100%=full color.

Lightness (0-100%)

How light or dark. 0%=black, 50%=pure color, 100%=white.

hsl(0, 100%, 50%)    /* Pure red */
hsl(120, 100%, 50%)  /* Pure green */
hsl(240, 100%, 50%)  /* Pure blue */
hsl(0, 0%, 0%)       /* Black */
hsl(0, 0%, 100%)     /* White */
hsl(0, 0%, 50%)      /* Gray */

Why HSL is Powerful

HSL makes color manipulation intuitive:

/* Creating color variations */
--brand-color: hsl(220, 80%, 50%);

/* Lighter version: increase lightness */
--brand-light: hsl(220, 80%, 70%);

/* Darker version: decrease lightness */
--brand-dark: hsl(220, 80%, 30%);

/* Muted version: decrease saturation */
--brand-muted: hsl(220, 30%, 50%);

When to Use HSL

  • Creating color palettes and variations
  • Building design systems with consistent colors
  • Dark mode themes (adjust lightness)
  • Hover states (slight lightness changes)

Modern CSS Color Functions

color-mix()

Mix two colors in a specified color space:

color-mix(in srgb, red 50%, blue)  /* Purple */
color-mix(in srgb, white 20%, var(--brand))  /* Tinted brand */

Relative Color Syntax

Create new colors based on existing ones:

/* Make a color 20% lighter */
hsl(from var(--color) h s calc(l + 20%))

/* Adjust hue by 30 degrees */
hsl(from var(--color) calc(h + 30) s l)

Color Conversion Formulas

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

hexToRgb("#FF5733"); // { r: 255, g: 87, b: 51 }

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: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };
}

Color Accessibility

Ensuring sufficient color contrast is essential for accessibility (WCAG guidelines):

Contrast Ratios

WCAG AA (Minimum)

4.5:1 for normal text, 3:1 for large text (18pt+ or 14pt bold)

WCAG AAA (Enhanced)

7:1 for normal text, 4.5:1 for large text

Calculating Contrast

function getLuminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(c => {
    c /= 255;
    return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
  });
  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}

function getContrastRatio(color1, color2) {
  const l1 = getLuminance(...color1);
  const l2 = getLuminance(...color2);
  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);
  return (lighter + 0.05) / (darker + 0.05);
}

Color Blindness Considerations

  • Don't rely on color alone to convey information
  • Use patterns, icons, or text labels alongside color
  • Test with color blindness simulators
  • Red-green color blindness is most common (~8% of males)

Building Color Palettes

60-30-10 Rule

A classic design principle:

  • 60%: Dominant/neutral color (backgrounds)
  • 30%: Secondary color (sections, cards)
  • 10%: Accent color (buttons, links, highlights)

Color Relationships

/* Complementary: opposite on color wheel */
--primary: hsl(220, 80%, 50%);     /* Blue */
--complement: hsl(40, 80%, 50%);   /* Orange (220 + 180) */

/* Analogous: adjacent on color wheel */
--primary: hsl(220, 80%, 50%);
--analogous1: hsl(190, 80%, 50%);  /* -30° */
--analogous2: hsl(250, 80%, 50%);  /* +30° */

/* Triadic: evenly spaced */
--primary: hsl(220, 80%, 50%);
--triadic1: hsl(340, 80%, 50%);    /* +120° */
--triadic2: hsl(100, 80%, 50%);    /* +240° */

Practical Tips

  • Use HSL for creating consistent color scales and themes
  • Use HEX for static color values and design handoffs
  • Use RGBA when you need transparency
  • Always check contrast ratios for text colors
  • Define color variables in one place (CSS custom properties)
  • Use semantic names (--color-error) not descriptive (--color-red)
  • Test colors on multiple screens—colors vary between devices

Convert Colors

Use our color converter to translate between HEX, RGB, and HSL formats.

Open Color Converter →