X Xerobit

Color Theory for Web Design — Hue, Saturation, and Color Harmonies

Color theory explains how colors relate to each other and why some combinations work visually. Here's how hue, saturation, and lightness work, common color harmonies, and how...

Mian Ali Khalid · · 6 min read
Use the tool
Color Picker
Pick colors, convert hex/RGB/HSL/OKLCH, and check WCAG contrast.
Open Color Picker →

Color theory provides a systematic framework for choosing colors that work together. Understanding hue, saturation, lightness, and color harmonies lets you build palettes intentionally rather than by trial and error.

Use the Color Picker to explore colors and build palettes online.

The color models

RGB (Red, Green, Blue)

How screens display color. Each channel is 0–255:

color: rgb(59, 130, 246);   /* Blue */
color: rgb(239, 68, 68);    /* Red */
color: rgb(16, 185, 129);   /* Green */

RGB is how monitors work but isn’t intuitive for design — changing one value affects multiple perceived properties simultaneously.

HSL (Hue, Saturation, Lightness)

More intuitive for design work:

color: hsl(217, 91%, 60%);  /* Blue */
color: hsl(0, 84%, 60%);    /* Red */
color: hsl(160, 84%, 39%);  /* Green */
  • Hue: The color itself (0–360°, the color wheel)
  • Saturation: Color intensity (0% = gray, 100% = vivid)
  • Lightness: Brightness (0% = black, 50% = full color, 100% = white)

HSL makes it easy to create color variations: keep hue fixed, vary saturation and lightness.

OKLCH (Perceptually Uniform)

Modern CSS color space with perceptually uniform lightness:

color: oklch(0.65 0.18 250);  /* Blue */
color: oklch(0.65 0.18 30);   /* Orange (same perceived brightness) */

In HSL, two colors at the same L value can appear different in brightness. OKLCH corrects this — same L = same perceived lightness. Better for generating accessible color scales.

The color wheel

The color wheel organizes colors by hue (0–360°):

0°/360°: Red
30°: Orange  
60°: Yellow
90°: Yellow-green
120°: Green
150°: Green-cyan
180°: Cyan
210°: Blue-cyan
240°: Blue
270°: Blue-magenta
300°: Magenta
330°: Red-magenta

Color harmonies

Color harmonies are combinations of hues that work together. They’re defined by their relationship on the color wheel.

Complementary

Two colors opposite on the wheel (180° apart):

/* Blue + Orange: */
--primary: hsl(217, 91%, 60%);   /* Blue */
--accent: hsl(37, 91%, 60%);     /* Orange */

High contrast, vibrant. Use one as the dominant color, the other for accents.

Analogous

Three colors adjacent on the wheel (30° apart):

/* Blue-Cyan-Teal range: */
--color-1: hsl(200, 80%, 50%);  /* Blue-Cyan */
--color-2: hsl(180, 80%, 40%);  /* Cyan */
--color-3: hsl(160, 70%, 40%);  /* Teal */

Natural, cohesive look. Comfortable to the eye, lower contrast than complementary.

Triadic

Three colors evenly spaced (120° apart):

/* Red + Yellow + Blue: */
--color-1: hsl(0, 80%, 55%);    /* Red */
--color-2: hsl(120, 80%, 40%);  /* Green */
--color-3: hsl(240, 80%, 60%);  /* Blue */

Vibrant and balanced, like primary colors. Requires care — let one dominate.

Split-complementary

A base color + two colors adjacent to its complement:

/* Blue base, split complement of orange: */
--base: hsl(217, 91%, 60%);      /* Blue */
--accent-1: hsl(20, 85%, 60%);   /* Red-Orange */
--accent-2: hsl(55, 85%, 55%);   /* Yellow-Orange */

Similar visual tension to complementary but more versatile.

Tetradic (Square)

Four colors evenly spaced (90° apart):

--color-1: hsl(0, 75%, 55%);    /* Red */
--color-2: hsl(90, 75%, 45%);   /* Green */
--color-3: hsl(180, 75%, 45%);  /* Cyan */
--color-4: hsl(270, 75%, 60%);  /* Purple */

Rich, complex palette. Keep saturation similar across all four.

Monochromatic

Single hue, varying saturation and lightness:

/* Blue scale: */
--blue-900: hsl(217, 91%, 20%);  /* Very dark */
--blue-700: hsl(217, 91%, 40%);  /* Dark */
--blue-500: hsl(217, 91%, 60%);  /* Base */
--blue-300: hsl(217, 91%, 75%);  /* Light */
--blue-100: hsl(217, 91%, 93%);  /* Very light */

Cohesive and professional. Limited differentiation — need neutrals for balance.

Building a design color palette

A practical design palette has:

:root {
  /* Primary: main brand color */
  --primary-50:  hsl(217, 91%, 97%);
  --primary-100: hsl(217, 91%, 93%);
  --primary-200: hsl(217, 91%, 85%);
  --primary-400: hsl(217, 91%, 70%);
  --primary-500: hsl(217, 91%, 60%);  /* Main */
  --primary-600: hsl(217, 91%, 50%);
  --primary-700: hsl(217, 91%, 40%);
  --primary-900: hsl(217, 91%, 20%);

  /* Neutral: text, backgrounds, borders */
  --gray-50:  hsl(220, 14%, 96%);
  --gray-100: hsl(220, 14%, 92%);
  --gray-200: hsl(220, 14%, 86%);
  --gray-400: hsl(220, 9%, 64%);
  --gray-600: hsl(220, 9%, 40%);
  --gray-900: hsl(220, 14%, 10%);

  /* Semantic: status colors */
  --success: hsl(142, 71%, 45%);
  --warning: hsl(38, 92%, 50%);
  --error:   hsl(0, 84%, 60%);
  --info:    hsl(199, 89%, 48%);
}

Color accessibility (contrast ratios)

WCAG 2.1 defines minimum contrast ratios:

ElementNormal textLarge text
AA (minimum)4.5:13:1
AAA (enhanced)7:14.5:1
/* Common combinations: */
/* White text on primary blue: */
color: white;
background: hsl(217, 91%, 40%);  /* hsl 40% is dark enough for white text */

/* Dark text on light background: */
color: hsl(217, 91%, 10%);
background: hsl(217, 91%, 97%);

/* Gray text (be careful): */
color: hsl(220, 9%, 46%);  /* May fail AA on white background — test it */

Use a contrast checker to verify your color combinations meet WCAG requirements before shipping.


Related posts

Related tool

Color Picker

Pick colors, convert hex/RGB/HSL/OKLCH, and check WCAG contrast.

Written by Mian Ali Khalid. Part of the Frontend & Design pillar.