Color Theory for Web Developers: HEX, RGB, HSL Explained
As a web developer, you work with colors every day — but do you truly understand the difference between #FF6B35, rgb(255, 107, 53), and hsl(16, 100%, 60%)? They all represent the same orange, yet each format has distinct advantages. This guide gives you practical knowledge of color spaces so you can make better design decisions and write cleaner CSS.
The RGB Additive Color Model
RGB (Red, Green, Blue) is the foundation of all digital color. Screens emit light, so colors are created by adding light together — this is called the additive color model.
- Each channel ranges from 0 (no light) to 255 (full intensity)
rgb(0, 0, 0)= black (no light)rgb(255, 255, 255)= white (all light)rgb(255, 0, 0)= pure red
How RGB Works
Each pixel on your screen has three sub-pixels (red, green, blue) that light up at different intensities. Your eyes blend these into a single perceived color. With 256 levels per channel, RGB can represent 16,777,216 colors (256 Ă— 256 Ă— 256).
RGB in CSS
.button {
/* Functional notation */
color: rgb(99, 102, 241);
/* With alpha transparency */
background: rgb(99 102 241 / 0.15);
/* Legacy notation with comma separator */
border-color: rgba(99, 102, 241, 0.5);
}
HEX Color Notation
HEX colors are simply RGB values written in hexadecimal (base-16). Each pair of hex digits represents one channel (00-FF = 0-255).
| Format | Example | Meaning |
|---|---|---|
| 6-digit | #6366F1 | R:99 G:102 B:241 |
| 3-digit shorthand | #F00 | Same as #FF0000 (pure red) |
| 8-digit (with alpha) | #6366F180 | 50% opacity (80 hex = 128 = ~50%) |
| 4-digit shorthand | #F008 | Same as #FF000088 |
Converting HEX to RGB
#6366F1
63 (hex) = 6Ă—16 + 3 = 99 (Red)
66 (hex) = 6Ă—16 + 6 = 102 (Green)
F1 (hex) = 15Ă—16 + 1 = 241 (Blue)
Result: rgb(99, 102, 241)
HEX is the most compact color format and the most common in CSS codebases. Its main downside is that it’s not human-readable — you can’t glance at #2DD4BF and know it’s teal.
HSL: The Intuitive Color Model
HSL (Hue, Saturation, Lightness) describes colors the way humans think about them. It’s far more intuitive for creating color palettes and making adjustments.
- Hue (0-360°): The color wheel position — 0°=red, 120°=green, 240°=blue
- Saturation (0-100%): Color intensity — 0%=gray, 100%=vivid
- Lightness (0-100%): Brightness — 0%=black, 50%=pure color, 100%=white
Why HSL Is Better for Design Systems
With HSL, creating consistent color variations is trivial:
:root {
/* Base brand color */
--brand: hsl(239, 84%, 67%);
/* Lighter version (increase lightness) */
--brand-light: hsl(239, 84%, 80%);
/* Darker version (decrease lightness) */
--brand-dark: hsl(239, 84%, 50%);
/* Muted version (decrease saturation) */
--brand-muted: hsl(239, 40%, 67%);
/* Hover state (slight adjustments) */
--brand-hover: hsl(239, 84%, 60%);
}
With RGB or HEX, creating these variations requires recalculating all three channels. With HSL, you adjust a single value.
CMYK: For Print Design
CMYK (Cyan, Magenta, Yellow, Key/Black) is the subtractive color model used in printing. While you won’t use CMYK in CSS, understanding it matters when your web colors need to translate to printed materials.
| Aspect | RGB (Screen) | CMYK (Print) |
|---|---|---|
| Model type | Additive (light) | Subtractive (ink) |
| White | All channels max | No ink (paper color) |
| Black | All channels zero | All inks max (or K channel) |
| Gamut | Wider (more colors) | Narrower (some colors can’t print) |
| Use case | Screens, web, digital | Brochures, packaging, signage |
Vibrant neon colors (highly saturated RGB values) often look dull when printed in CMYK because they fall outside the printable gamut. Always proof your brand colors in both spaces.
When to Use Each Format
| Format | Best For | Advantages |
|---|---|---|
| HEX | Static color values, design tokens | Compact, widely supported, copy-paste friendly |
| RGB | Programmatic color manipulation | Direct channel access, easy alpha blending |
| HSL | Design systems, theming, palettes | Intuitive adjustments, readable variations |
| CMYK | Print design specifications | Accurate print reproduction |
Accessibility: Color Contrast Requirements
Choosing beautiful colors means nothing if your users can’t read the text. WCAG 2.1 defines minimum contrast ratios:
| Level | Normal Text | Large Text (18px+ bold or 24px+) |
|---|---|---|
| AA (minimum) | 4.5:1 | 3:1 |
| AAA (enhanced) | 7:1 | 4.5:1 |
Tips for Accessible Color Choices
- Never rely on color alone to convey information — add icons, labels, or patterns
- Test your palette with color blindness simulators (8% of males have color vision deficiency)
- Dark backgrounds need lighter text — aim for lightness difference of at least 50% in HSL
- Avoid pure gray text on white (
#777on#FFFfails AA for small text)
Modern CSS Color Features
CSS is evolving beyond sRGB with new color spaces:
oklch(): Perceptually uniform lightness, ideal for consistent palettescolor(display-p3 ...): Wider gamut for modern displayscolor-mix(): Blend two colors in any color space- Relative color syntax: Derive colors from other colors dynamically
/* Modern CSS color features */
.card {
/* P3 wide-gamut color */
background: color(display-p3 0.4 0.2 0.9);
/* Mix two colors */
border-color: color-mix(in oklch, #6366f1 70%, white);
}
Try it yourself: Convert between HEX, RGB, HSL, and CMYK instantly with our free Color Converter — visualize colors in real time and copy CSS-ready values.