The Shack Design Tips Color Theory for Developers

Color Theory for Developers: HEX, RGB, and HSL Explained

Back to All Posts

Designers speak in HEX. Design systems use HSL. APIs return RGB. Canvas operations need numbers. At some point every developer needs to understand all three color formats, why they exist, and how to move between them. The DevToolShack Color Picker converts between all formats instantly — but understanding why they differ makes you far more effective when working with color in CSS and code.

HEX: The Web's Native Format

HEX colors are the format most developers encounter first. A HEX color is just an RGB color written in base-16 (hexadecimal):

#ff6b35   /* full 6-digit hex */
#f63       /* shorthand — same as #ff6633 */
#ff6b35cc /* 8-digit hex — last two digits are alpha (opacity) */

The six characters split into three pairs: RR GG BB. Each pair ranges from 00 to ff — that's 0 to 255 in decimal.

So #ff6b35 means:

  • Red: ff = 255 (maximum)
  • Green: 6b = 107
  • Blue: 35 = 53

When to use HEX: Any time you're copying colors from a design file, brand palette, or another developer. It's the universal handshake format — compact, familiar, supported everywhere.

RGB: The Additive Model

RGB is HEX with the numbers decoded — same information, different notation:

color: rgb(255, 107, 53);
color: rgb(255 107 53);         /* modern space-separated syntax */
color: rgba(255, 107, 53, 0.8); /* with alpha channel */
color: rgb(255 107 53 / 0.8);   /* modern syntax with alpha */

Each channel runs from 0 to 255. All three at 0 = black. All three at 255 = white.

When to use RGB: When you need to manipulate color values in JavaScript or CSS calculations. rgb() makes it easy to dynamically adjust values:

// Dynamically building a color in JS
const opacity = 0.5;
const color = `rgba(255, 107, 53, ${opacity})`;

// Or with CSS custom properties
element.style.setProperty('--brand-opacity', opacity);

HSL: The Human-Readable Format

HSL stands for Hue, Saturation, Lightness — and it's the format that makes the most intuitive sense for working with color relationships:

color: hsl(16, 100%, 60%);
color: hsl(16deg 100% 60%);       /* modern syntax */
color: hsl(16 100% 60% / 0.8);    /* with alpha */
  • Hue (0–360) — the angle on the color wheel. 0/360 = red, 120 = green, 240 = blue.
  • Saturation (0–100%) — how vivid the color is. 0% = grey, 100% = fully saturated.
  • Lightness (0–100%) — how light or dark. 0% = black, 50% = the "pure" color, 100% = white.

Why HSL is powerful for theming: Want a lighter version of your brand color? Just increase the lightness. Want a muted version? Decrease saturation. Want the complementary color? Add 180 to the hue. These adjustments are impossible to reason about in HEX or RGB.

:root {
  --brand-h: 16;
  --brand-s: 100%;

  --brand:       hsl(var(--brand-h) var(--brand-s) 60%);
  --brand-light: hsl(var(--brand-h) var(--brand-s) 80%);
  --brand-dark:  hsl(var(--brand-h) var(--brand-s) 40%);
  --brand-muted: hsl(var(--brand-h) 30% 60%);
}

This pattern — separating hue and saturation as custom properties — is the backbone of many modern design systems. Change --brand-h and the entire theme shifts.

The Alpha Channel

All three formats support transparency:

/* All produce the same result: brand color at 50% opacity */
color: #ff6b3580;           /* 8-digit hex — 80 hex = 128 dec = ~50% */
color: rgba(255, 107, 53, 0.5);
color: hsl(16 100% 60% / 0.5);

The alpha channel ranges from 0 (fully transparent) to 1 (fully opaque) in RGB/HSL, and from 00 to ff in 8-digit HEX.

Choosing a Format: Quick Guide

SituationBest Format
Copying from Figma or a design fileHEX (what designers export)
Building a color system or themeHSL with CSS custom properties
Dynamic color manipulation in JSRGB (easy arithmetic)
Transparency/opacityHSL or RGBA
Canvas / WebGLRGB (0–1 float scale)
Sharing with other developersHEX (universal recognition)

Color Contrast and Accessibility

Whatever format you use, contrast matters. The WCAG 2.1 guidelines require a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text. The Color Contrast Checker calculates the ratio between any two colors instantly — paste your foreground and background colors and see whether they pass AA or AAA compliance.

Lightness in HSL gives you a rough intuition for contrast — a dark text on a light background has a large lightness difference. But always verify with the actual contrast ratio, since saturation affects perceived brightness in ways that aren't always intuitive.

Full color toolkit: The Color Picker converts between HEX, RGB, HSL, and HSV. The Palette Generator builds a full palette from a single color. The Tint & Shade Generator produces lightness variations. The Image Color Extractor pulls a palette from any image.