HEX vs RGB vs HSL: Color Format Guide for Web Developers
Understand the differences between HEX, RGB, and HSL color formats. Learn when to use each, how to convert between them, and practical tips for CSS color management.
Try our free Color Converter
Convert between HEX, RGB, HSL, CMYK with WCAG contrast checker and palette generator.
Understanding Color Models for the Web
Every color on your screen is produced by mixing light. Web browsers support several ways to describe these colors in CSS, but the three most common are HEX, RGB, and HSL. Each uses a different notation to describe the same set of approximately 16.7 million colors available in the sRGB color space.
HEX and RGB are closely related — they both define colors by specifying how much red, green, and blue light to mix. HSL takes a different approach, describing colors in terms of hue (which color), saturation (how vivid), and lightness (how bright). This makes HSL more intuitive for humans, even though browsers convert it to RGB under the hood.
Choosing the right format depends on your workflow. Designers often prefer HSL for creating palettes, while developers frequently use HEX because it's compact. Understanding all three lets you pick the best tool for each situation, and our Color Converter makes it easy to switch between them instantly.
HEX Colors Explained
HEX (hexadecimal) color codes are the most widely used color format on the web. A HEX code is a 6-digit string prefixed with #, where each pair of digits represents the intensity of red, green, and blue channels in hexadecimal (base 16):
#FF5733 ││││││ ││││└└── Blue: 0x33 = 51 (0-255) ││└└──── Green: 0x57 = 87 (0-255) └└────── Red: 0xFF = 255 (0-255)
Shorthand HEX (#RGB)
When each pair has identical digits, you can use the 3-digit shorthand. The browser doubles each digit:
#RGB → #RRGGBB #F00 → #FF0000 (pure red) #0F0 → #00FF00 (pure green) #09C → #0099CC (steel blue) #FFF → #FFFFFF (white) #000 → #000000 (black)
8-Digit HEX (#RRGGBBAA)
Modern browsers support an 8-digit HEX format that adds an alpha (transparency) channel. The last two digits specify opacity from 00 (fully transparent) to FF (fully opaque):
#FF573380 → rgb(255, 87, 51) at 50% opacity #FF5733FF → rgb(255, 87, 51) at 100% opacity (same as #FF5733) #FF573300 → rgb(255, 87, 51) at 0% opacity (invisible) /* 4-digit shorthand also works: */ #F008 → rgba(255, 0, 0, 0.53)
Pros: Compact, universally supported, easy to copy-paste from design tools. Cons: Not human-readable — it's hard to tell what color #2D8CFF is just by looking at it.
RGB and RGBA
RGB is the functional notation for the same red-green-blue model. Each channel takes a value from 0 to 255 (or 0% to 100%):
/* Classic comma syntax */ color: rgb(255, 87, 51); /* red-orange */ color: rgb(0, 128, 255); /* bright blue */ /* With alpha (transparency) */ color: rgba(255, 87, 51, 0.5); /* 50% transparent */ color: rgba(0, 0, 0, 0.8); /* 80% opaque black */ /* Percentage values */ color: rgb(100%, 34%, 20%); /* same as rgb(255, 87, 51) */
How RGB Maps to HEX
The conversion is straightforward: each decimal value (0-255) maps to a two-digit hex value (00-FF). For example:
| RGB | HEX | Color |
|---|---|---|
| rgb(255, 0, 0) | #FF0000 | Pure red |
| rgb(0, 128, 0) | #008000 | Dark green |
| rgb(0, 0, 255) | #0000FF | Pure blue |
| rgb(255, 255, 255) | #FFFFFF | White |
| rgb(128, 128, 128) | #808080 | Gray |
When to use RGB:RGB is useful when you need to manipulate color channels programmatically. In JavaScript, canvas APIs and image processing libraries work with RGB values natively. It's also clearer than HEX when reading code, since the decimal values are more intuitive than hex codes.
HSL and HSLA — The Human-Friendly Format
HSL describes colors the way humans think about them, using three intuitive properties:
- Hue (H) — The color itself, expressed as an angle on the color wheel from 0 to 360 degrees. 0/360 is red, 120 is green, 240 is blue, 60 is yellow, 180 is cyan, 300 is magenta.
- Saturation (S) — How vivid or pure the color is, from 0% (gray) to 100% (fully saturated). Think of it as adding or removing gray.
- Lightness (L) — How light or dark the color is, from 0% (black) to 100% (white). 50% gives you the pure, most vivid version of the hue.
/* HSL syntax */ color: hsl(11, 100%, 60%); /* red-orange (#FF5733) */ color: hsl(210, 100%, 50%); /* bright blue (#0080FF) */ color: hsl(0, 0%, 50%); /* gray (#808080) */ /* With alpha */ color: hsla(11, 100%, 60%, 0.5); /* 50% transparent red-orange */ /* Creating variations is intuitive: */ color: hsl(210, 100%, 30%); /* dark blue */ color: hsl(210, 100%, 50%); /* medium blue */ color: hsl(210, 100%, 70%); /* light blue */ color: hsl(210, 100%, 90%); /* very light blue */ color: hsl(210, 30%, 50%); /* desaturated (muted) blue */
The real power of HSL is how easy it makes creating color variations. Need a hover state that's slightly darker? Subtract 10 from the lightness. Need a muted background version? Drop the saturation. Need a complementary color? Add 180 to the hue. With HEX or RGB, these operations require adjusting all three channels simultaneously, which is much harder to do intuitively.
/* Design system with HSL — one hue, many variations */
:root {
--brand-hue: 210;
--brand: hsl(var(--brand-hue), 100%, 50%);
--brand-light: hsl(var(--brand-hue), 100%, 70%);
--brand-dark: hsl(var(--brand-hue), 100%, 30%);
--brand-muted: hsl(var(--brand-hue), 30%, 50%);
--brand-bg: hsl(var(--brand-hue), 100%, 95%);
}
/* Change the entire color scheme by updating one variable! */You can experiment with HSL values and instantly see the results using our Color Converter tool, which also checks WCAG contrast ratios for accessibility.
When to Use Each Format
| Format | Best For | Pros | Cons |
|---|---|---|---|
| HEX | Copy-pasting from design tools, inline styles, quick prototyping | Compact, universally recognized, supported everywhere | Not human-readable, hard to adjust manually |
| RGB | Programmatic color manipulation, canvas/WebGL, image processing | Direct channel control, matches how screens work | Verbose, hard to create variations intuitively |
| HSL | Design systems, theming, creating color palettes, hover states | Human-intuitive, easy to create variations, great for CSS variables | Slightly less familiar to some developers |
- For design systems and theming — Use HSL. Define your brand hue once and derive all variations (light, dark, muted, background) by adjusting saturation and lightness. This makes theme switching trivial.
- For one-off colors from a designer — Use HEX. Designers typically provide HEX codes, and they're the most compact format for hardcoded values.
- For dynamic colors in JavaScript — Use RGB or HSL depending on what you're doing. Canvas and image APIs use RGB natively. For generating palettes or color animations, HSL is easier to work with.
- For accessibility — Any format works, but HSL makes it easier to verify contrast because you can see the lightness value at a glance. Pair any format with a contrast checker to ensure WCAG compliance.
Color Formats in CSS
CSS has evolved significantly in how it handles colors. Here's what's available today:
Legacy Syntax (Comma-Separated)
/* These work everywhere, including old browsers */ color: rgb(255, 87, 51); color: rgba(255, 87, 51, 0.5); color: hsl(11, 100%, 60%); color: hsla(11, 100%, 60%, 0.5);
Modern Syntax (Space-Separated with Slash for Alpha)
The CSS Color Level 4 specification introduced a cleaner syntax that all modern browsers support:
/* Modern syntax — spaces, no commas, slash for alpha */ color: rgb(255 87 51); color: rgb(255 87 51 / 50%); /* replaces rgba() */ color: hsl(11 100% 60%); color: hsl(11 100% 60% / 50%); /* replaces hsla() */ /* You can also use decimals for alpha: */ color: rgb(255 87 51 / 0.5); color: hsl(11 100% 60% / 0.5);
CSS Named Colors
CSS defines 148 named colors. They're convenient but limited:
color: red; /* #FF0000 */ color: tomato; /* #FF6347 */ color: dodgerblue; /* #1E90FF */ color: rebeccapurple; /* #663399 */ color: transparent; /* rgba(0, 0, 0, 0) */ color: currentColor; /* inherits from parent's color */
New CSS Color Functions
CSS Color Level 4 also introduced new color spaces with wider gamut support:
/* Relative color syntax — modify existing colors */ --brand: hsl(210 100% 50%); --brand-light: hsl(from var(--brand) h s 80%); /* lighter */ --brand-muted: hsl(from var(--brand) h 30% l); /* desaturated */ /* color-mix() — blend two colors */ color: color-mix(in srgb, #FF0000, #0000FF); /* purple */ color: color-mix(in srgb, blue 70%, white); /* light blue */ /* Wide gamut (P3 display) */ color: color(display-p3 1 0.5 0); /* vivid orange */ /* oklch — perceptually uniform */ color: oklch(70% 0.15 210); /* balanced blue */
For working with CSS gradients using any of these color formats, try our CSS Gradient Generator. For converting between CSS units like px, rem, and em, check out the CSS Unit Converter.
Frequently Asked Questions
What is the difference between HEX and RGB?
Why should I use HSL instead of HEX?
Do all browsers support HSL?
How do I add transparency to a color in CSS?
Convert Colors Now
Convert between HEX, RGB, HSL, CMYK with WCAG contrast checker and palette generator. Free, private, runs in your browser.
Open Color Converter