#3B82F6, rgb(59, 130, 246), hsl(217, 91%, 60%) — three completely different-looking strings, one identical pixel on screen. If you've ever wondered why CSS gives you three (or more) ways to write the exact same blue, you're not missing something obvious. There genuinely isn't one "correct" format — there's a best format for whatever you're trying to do at that moment.
This guide breaks down what each format actually stores under the hood, when to reach for which one, and how they relate to each other — with a live converter so you can see all three side by side for any color right now.
🧪 Try It: Live HEX / RGB / HSL Converter
✦ Why Three Color Formats Exist
Every pixel on your screen is made of tiny red, green, and blue light emitters. Varying each channel's intensity from 0 to 255 produces roughly 16.7 million distinct colors — that's the entire color space every format below is describing, just with different math on top.
Think of it like temperature: Celsius, Fahrenheit, and Kelvin all measure the exact same heat, but each is more convenient in a different context. Color formats work the same way — same underlying reality, different tool for different job.
#️⃣ HEX Explained
Breaking down #3B82F6:
3B→ Red channel = 59 in decimal82→ Green channel = 130 in decimalF6→ Blue channel = 246 in decimal
HEX also supports a shorthand (#FFF expands to #FFFFFF) and an 8-digit variant with an alpha channel, like #3B82F680 for roughly 50% opacity. It's compact and universal — but genuinely hard to "read" at a glance. Quick: what color is #0F52B7? Most people can't picture it without pasting it into a tool.
🎛️ RGB Explained
The same blue as decimal: rgb(59, 130, 246). Add transparency with a fourth value: rgba(59, 130, 246, 0.5), or the modern space-separated syntax: rgb(59 130 246 / 0.5).
RGB shines whenever a human doesn't need to "read" the color directly but code does need to manipulate it — averaging two colors, animating a channel, or extracting values from an uploaded image, for example.
🎨 HSL Explained
| Channel | Range | What It Controls |
|---|---|---|
| Hue | 0–360° | Base color — 0° red, 120° green, 240° blue |
| Saturation | 0–100% | Intensity — 0% is grayscale, 100% is fully vivid |
| Lightness | 0–100% | Brightness — 0% black, 50% pure hue, 100% white |
Once you internalize this, a value like hsl(0, 100%, 50%) is instantly readable as pure red — and want a darker, richer version? Just drop lightness to hsl(0, 70%, 40%). Want the same richness in blue instead? Change the hue to 240 and nothing else. That single-number control is HSL's superpower.
🧭 Which Format Should You Use? (Decision Guide)
| Situation | Best Format | Why |
|---|---|---|
| Storing a fixed brand color | HEX | Compact, universal, pastes straight from design tools |
| Manipulating channels in JS | RGB | Values map directly to array indices and simple math |
| Deriving hover/active/disabled states | HSL | Change one number (lightness) — no recalculating three channels |
| Adding transparency | RGBA / 8-digit HEX | Explicit alpha channel, widely supported |
| Building a light/dark theme system | HSL | Store hue once, derive every shade from lightness |
| Reading a designer's spec sheet | HEX | Industry-standard handoff format |
Notice there's no single winner — the "best" answer changes with the task in front of you, which is exactly why professionals keep all three in their toolkit rather than picking a permanent favorite.
🔍 Adding Transparency: RGBA, HSLA, and 8-Digit HEX
.modal-overlay {
background: rgba(0, 0, 0, 0.5); /* 50% black */
}
.tooltip {
background: hsla(210, 100%, 50%, 0.9); /* 90% opaque blue */
}
.badge {
background: #3B82F680; /* ~50% opacity, 8-digit HEX */
} 8-digit HEX has roughly 96% global browser support — excellent for modern projects, but worth double-checking if you still need to support very old browsers.
🎨 Convert Any Color Instantly
Switch between HEX, RGB and HSL, generate tints and shades, and explore harmonious palettes — free, no signup, right in your browser.
Open the Free Color Picker →🎭 Theming and CSS Variables With HSL
:root {
--hue: 217;
--accent: hsl(var(--hue), 91%, 60%);
--accent-light: hsl(var(--hue), 91%, 80%);
--accent-dark: hsl(var(--hue), 91%, 40%);
}
/* Switch to a green theme? Just change one number: */
[data-theme="green"] { --hue: 142; } This pattern is why many CSS-heavy teams default to HSL for design-system tokens even when the final brand values started life as HEX from a designer's file — the two formats aren't rivals, they're tools for different stages of the same workflow.
♿ Color Format and Accessibility
This is an easy trap: a color system built entirely in HSL might assume "same lightness = same readability," but WCAG doesn't calculate contrast that way. Once you've picked your colors in whichever format suits your workflow, run the final pair through a contrast checker — see our WCAG 2.2 contrast guide for the exact AA/AAA thresholds and real examples.
🚀 Beyond HSL: A Quick Note on OKLCH
You don't need OKLCH to work effectively with color today — HEX, RGB, and HSL comfortably cover the vast majority of real projects. But if you're building large-scale color systems, smooth gradients, or supporting wide-gamut displays, it's worth knowing OKLCH exists as the next step up once you outgrow HSL's limitations.
🚫 Common Color Format Mistakes
- Treating HSL lightness as WCAG contrast. They're different math — always verify the real ratio.
- Hardcoding hover states in HEX. Recalculating three channels by hand for every state is tedious and error-prone — HSL does it in one number.
- Assuming one format is "faster." All standard formats have identical rendering performance in modern browsers.
- Forgetting 8-digit HEX browser support gaps. ~96% global support is excellent but not universal — check your audience if legacy support matters.
- Mixing formats inconsistently across a codebase. Pick a convention per use case (e.g., HEX for tokens, HSL for derived states) and document it.
- Skipping the actual contrast check. No format guarantees accessible contrast on its own — that always needs a dedicated test.
🏁 Conclusion
There's no universally "best" color format — only the best format for the specific operation in front of you. Reach for HEX when storing fixed brand values or pasting from a design tool, RGB when manipulating channels in JavaScript or adding straightforward transparency, and HSL whenever you need to hand-derive tints, shades, or interactive states from a single base color.
All three describe the exact same sRGB colors — conversion between them is lossless, so there's no risk in switching formats mid-project as your needs change. Use the converter above whenever you need to jump between them, and once your final palette is locked in, always run it through a contrast checker before shipping.
❓ Frequently Asked Questions
What's the difference between HEX and RGB?
HEX and RGB describe the exact same sRGB color in different notations. HEX writes each channel as a two-digit hexadecimal byte (00-FF), while RGB writes the same value as a decimal number from 0-255. #3B82F6 and rgb(59, 130, 246) are identical colors.
When should I use HSL instead of RGB?
Use HSL when you need to hand-derive color variations like hover states, tints, or shades, since you can change just the lightness or saturation number while keeping the hue constant. RGB requires recalculating all three channels to achieve the same effect.
Can HEX codes have transparency?
Yes, modern browsers support 8-digit HEX codes where the last two characters represent an alpha channel, such as #3B82F680 for roughly 50% opacity. This has about 96% global browser support but isn't available in older browsers like Internet Explorer.
Which color format is best for CSS variables?
HSL is often preferred for CSS variables because you can store the hue as one variable and derive lighter or darker variants by changing only the lightness value, making theme systems easier to maintain than separate HEX values for every shade.
Is one color format faster or better for performance?
No, all standard color formats have identical rendering performance in modern browsers. The choice between HEX, RGB, and HSL should be based on workflow and maintainability, not performance.
What do the H, S and L values in HSL mean?
H (hue) is the position on the color wheel from 0-360 degrees, where 0 is red and 240 is blue. S (saturation) is color intensity from 0% (grayscale) to 100% (fully saturated). L (lightness) ranges from 0% (black) through 50% (pure color) to 100% (white).
Why is HSL considered more human-readable than HEX?
HSL values map to how people naturally describe color — a hue, how vivid it is, and how light or dark it is. Most people can't picture what a hex code like #0F52B7 looks like, but hsl(210, 90%, 40%) is easy to reason about as a fairly dark, vivid blue.
Should I use HEX or RGB for storing brand colors?
HEX is the standard for storing fixed brand colors because it's compact, universally supported, and pastes directly from design tools like Figma or Sketch without conversion.
Does HSL lightness match WCAG contrast requirements?
No. HSL lightness is a simple average of the RGB channels and does not match WCAG's relative luminance calculation, which weights green more heavily than blue. Two colors with the same HSL lightness can have very different contrast ratios against the same background.
How do I convert between HEX, RGB and HSL?
All three formats represent the same underlying sRGB color, so conversion is lossless. Use a color converter tool to switch between formats instantly rather than calculating the math by hand.