Tools December 14, 2024 12 min read

Understanding Color Codes: HEX, RGB, and HSL

A comprehensive guide to digital color systems - learn how HEX, RGB, and HSL work and when to use each format in web design and development.

The first time I tried to match a brand color from a PDF to a website, I spent an embarrassing amount of time failing. The PDF showed a warm orange. I typed something that looked close. The browser rendered something that looked pink. The problem wasn't my eyes — it was that I didn't understand what those six characters after the hash sign actually meant. Once you understand the encoding, color codes stop being opaque strings and start being readable numbers.

What a Hex Code Actually Encodes

A hex color like #FF6347 is three pairs of hexadecimal numbers. The first pair is red, the second is green, the third is blue. Each pair runs from 00 (none of that color) to FF (maximum, which is 255 in decimal). So #FF6347 is 255 red, 99 green, 71 blue — which is the tomato red that CSS literally names "tomato."

Why hex? Because two hexadecimal digits can represent exactly 256 values (0–255), which matches one byte of color data. Three bytes gives you 256 × 256 × 256 = roughly 16.7 million possible colors. That's the origin of the phrase "millions of colors" you see in display specs — it's not marketing language, it's a direct consequence of the math.

Why is #000000 black and #FFFFFF white? Because computer screens use additive color mixing. Physical paint subtracts wavelengths; screens add light. No light at all is black (all channels at 0). Maximum light from all three channels combines to white (all channels at 255). This is the opposite of how a paint mixing class works, which is why it trips people up at first.

A few useful examples to anchor the pattern: #1E90FF is Dodger Blue (30 red, 144 green, 255 blue — heavy blue channel), #FFD700 is Gold (full red, strong green, no blue — red + green = yellow in additive mixing), and #808080 is a medium gray (equal amounts of each channel at the midpoint). Once you see the pattern, you can roughly read hex values without a picker.

RGB and Why It's Useful in Code

The rgb() function in CSS is just hex written in decimal. rgb(255, 99, 71) is the same tomato as #FF6347. The advantage of the function form is that it's easier to manipulate programmatically. If you're writing JavaScript and want to gradually shift a color, doing arithmetic on decimal numbers is simpler than doing it on hex strings.

RGB is also the natural format for anything that works directly with pixel data — Canvas API, WebGL, image processing libraries. These systems think in terms of channel values, so RGB is closer to the metal. When you're generating colors algorithmically or animating them, RGB keeps the math clean.

The weakness of RGB for human use is that it's not intuitive to adjust. If you want a slightly lighter version of a color, you can't just add 20 to one number and expect a predictable result. Increasing the red channel doesn't just "add red" in any way that feels visually predictable — it shifts the hue as well. This is where HSL becomes genuinely useful.

Why Designers Prefer HSL

HSL stands for Hue, Saturation, and Lightness. It represents the same colors as RGB but organizes them around how humans perceive color rather than how screens generate it. Hue is a degree on a color wheel (0° and 360° are both red, 120° is green, 240° is blue). Saturation is a percentage from gray (0%) to full color (100%). Lightness runs from black (0%) to white (100%), with pure color at 50%.

The practical power of HSL becomes obvious the moment you want to tweak a color. Want a lighter version? Increase the lightness value. Want a muted, desaturated version? Drop the saturation. Want the complementary color? Add 180 to the hue. None of those operations are easy to reason about in RGB or hex. That's why CSS design systems almost universally define their color palettes in HSL, even if they store them as hex tokens for browser compatibility.

HSL is also more natural for generating color themes. If you pick a brand hue and want to create a full palette of tints and shades, you can hold the hue constant and vary lightness in predictable steps. Try doing that in RGB and you'll find yourself reaching for a color picker anyway.

Alpha Channel: Transparency in Hex and RGBA

Transparency adds a fourth channel, called alpha. In CSS, rgba(255, 99, 71, 0.5) is tomato at 50% opacity — the alpha goes from 0.0 (fully transparent) to 1.0 (fully opaque). You can also write it as hsla(9, 100%, 64%, 0.5) if you prefer the HSL format.

Modern CSS also supports an 8-digit hex format: #FF634780, where the last two hex digits encode the alpha. 80 in hex is 128 in decimal, which is roughly 50% of 255. This format is convenient when you're storing colors as single strings rather than function calls, though browser support for it only solidified around 2018, so older code tends to use rgba() instead.

A common pitfall: opacity in CSS and alpha in rgba behave differently. Setting opacity: 0.5 on an element makes the entire element — including its children — 50% transparent. Using rgba for a background color only makes that color transparent, while the element's text remains fully opaque. When you want a semi-transparent background behind readable text, rgba is the right tool.

Which Format to Use When

For web development, the practical answer is: hex for static colors stored in design tokens, HSL for anything you're computing or theming, and rgba when you need transparency without affecting child elements. The formats are interchangeable in the browser — pick whichever one keeps your code readable for a given context.

If you're passing colors between a design tool and code, hex is the most universally supported format. Figma, Sketch, and most design tools export in hex by default. When you receive a hex value from a designer and need to create a tint/shade palette from it, convert to HSL first, adjust the lightness, then convert back if needed. Tools like Color Converter handle these conversions instantly.

One thing worth knowing: named CSS colors like tomato, dodgerblue, or cornflowerblue are just aliases for specific hex values defined in the CSS spec. They're handy for quick prototyping but most teams avoid them in production code because they're less precise and harder to search for systematically. For a full reference, the MDN named colors list covers all 140+ values with their hex equivalents. And if you want to understand the color science behind why these models work, the W3C CSS Color Level 4 spec is the authoritative reference — it's surprisingly readable for a spec document.