Color Models for Web Development
Different color models describe the same colors in different ways. Understanding when to use each makes your work faster and your code more maintainable.
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-255 (8-bit = 256 values per channel).
Red: 0 ──────────────────── 255
Green: 0 ──────────────────── 255 → 16.7 million possible colors
Blue: 0 ──────────────────── 255
Common RGB Values
| Color | RGB |
|---|---|
| Black | rgb(0, 0, 0) |
| White | rgb(255, 255, 255) |
| Red | rgb(255, 0, 0) |
| Green | rgb(0, 255, 0) |
| Blue | rgb(0, 0, 255) |
| Yellow | rgb(255, 255, 0) |
| Cyan | rgb(0, 255, 255) |
| Magenta | rgb(255, 0, 255) |
| Gray | rgb(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's rgb(147, 112, 219)? Hard to visualize. (It's 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= 080= 128 (halfway)FF= 255
When to Use HEX
- Most common format in design tools and codebases
- Compact representation
- Easy to copy/paste from design tools
- Good for color constants/variables
Drawbacks
Same problem as RGB - not intuitive for manipulation. What color is 20% lighter than #3498db? You can't easily calculate it.
HSL (Hue, Saturation, Lightness)
The most intuitive model for designers and developers. Maps directly to how we 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-360): Position on the color wheel
0°/360° = Red
60° = Yellow
120° = Green
180° = Cyan
240° = Blue
300° = Magenta
Saturation (0-100%): Intensity of the color
0% = Gray (no color)
50% = Muted
100% = Vivid, pure color
Lightness (0-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 shines:
:root {
/* Base color */
--primary: hsl(220, 90%, 50%);
/* Lighter version - just increase lightness */
--primary-light: hsl(220, 90%, 70%);
/* Darker version - just decrease lightness */
--primary-dark: hsl(220, 90%, 30%);
/* Muted version - decrease saturation */
--primary-muted: hsl(220, 40%, 50%);
/* Hover state - slightly different lightness */
--primary-hover: hsl(220, 90%, 45%);
}
When to Use HSL
- Color manipulation - Creating tints, shades, hover states
- Building color scales - Systematic lightness/saturation steps
- Design systems - Consistent color relationships
- Dark mode - Easy to adjust 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 uses HSB, you'll need to convert to HSL or RGB for CSS.
Comparison Table
| Model | Format | Intuitive? | CSS Support | Best For |
|---|---|---|---|---|
| RGB | rgb(255, 128, 0) | No | Yes | Programmatic manipulation |
| HEX | #FF8000 | No | Yes | Constants, copy/paste |
| HSL | hsl(30, 100%, 50%) | Yes | Yes | Design work, variations |
| HSB | hsb(30, 100%, 100%) | Yes | No | Design 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 on a color value and cycle through formats (Shift+Click on the color swatch in Chrome/Firefox).
Modern CSS: OKLCH and LCH
Newer color spaces that are more perceptually uniform (equal steps in values = equal perceived differences).
/* LCH: Lightness, Chroma, Hue */
color: lch(50% 100 270);
/* OKLCH: Improved version */
color: oklch(60% 0.15 250);
These are gaining browser support and are better for:
- Creating perceptually even color scales
- Maintaining consistent perceived contrast
- Wider color gamut displays
For now, HSL handles most needs, but watch OKLCH for the future.
Practical Recommendations
- Store colors as HEX in your design tokens/constants
- Use HSL for CSS when you need variations
- Use RGB for JavaScript color manipulation
- Use CSS custom properties with HSL 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
| Model | Remember |
|---|---|
| RGB | 0-255 for each channel, foundation of digital color |
| HEX | RGB in base-16, most common format |
| HSL | Hue (0-360), Saturation (0-100%), Lightness (0-100%) - use this |
| HSB | Design tools use this, convert to HSL for CSS |
Next: 03-color-wheel.md - Understanding color relationships