Web Colors: HEX, RGB, HSL Explained Simply
Understand color formats: HEX, RGB, HSL, RGBA. When to use which and how to convert.
Introduction to Web Colors
Colors are fundamental to web design, and understanding different color formats is essential for every developer. Whether you're working with CSS, designing interfaces, or ensuring accessibility, knowing how HEX, RGB, and HSL work helps you make better decisions. This guide explains each format, when to use them, and how to convert between them.
HEX Colors
Understanding HEX Format
HEX (hexadecimal) is the most common color format in web development. It represents colors as six-digit codes preceded by a hash symbol:
#RRGGBB
Examples:
#FF0000 → Red
#00FF00 → Green
#0000FF → Blue
#FFFFFF → White
#000000 → Black
#808080 → Gray
How HEX Works
Each pair of digits represents a color channel (0-255 in decimal, 00-FF in hex):
- First pair (RR): Red intensity (00-FF)
- Second pair (GG): Green intensity (00-FF)
- Third pair (BB): Blue intensity (00-FF)
#3498DB breakdown:
34 → Red = 52 (decimal)
98 → Green = 152 (decimal)
DB → Blue = 219 (decimal)
Shorthand HEX
When each pair has identical digits, use the 3-digit shorthand:
#FF0000 → #F00
#00FF00 → #0F0
#336699 → #369
#AABBCC → #ABC
HEX with Alpha
Modern browsers support 8-digit HEX for transparency:
#RRGGBBAA
#FF000080 → Red at 50% opacity
#3498DBCC → Blue at 80% opacity
// Or 4-digit shorthand
#F008 → Red at 50% opacity
RGB Colors
Understanding RGB Format
RGB directly specifies red, green, and blue values from 0 to 255:
rgb(red, green, blue)
Examples:
rgb(255, 0, 0) → Red
rgb(0, 255, 0) → Green
rgb(0, 0, 255) → Blue
rgb(255, 255, 255) → White
rgb(0, 0, 0) → Black
RGBA for Transparency
Add an alpha channel (0 to 1) for transparency:
rgba(red, green, blue, alpha)
rgba(255, 0, 0, 0.5) → 50% transparent red
rgba(0, 0, 0, 0.8) → 80% opaque black
rgba(255, 255, 255, 0) → Fully transparent
Modern RGB Syntax
CSS Color Level 4 allows a cleaner syntax:
// Space-separated values
rgb(255 0 0)
rgb(255 0 0 / 50%) → With alpha as percentage
rgb(255 0 0 / 0.5) → With alpha as decimal
// Percentage values
rgb(100% 0% 0%) → Same as rgb(255 0 0)
HSL Colors
Understanding HSL Format
HSL (Hue, Saturation, Lightness) is more intuitive for color manipulation:
hsl(hue, saturation, lightness)
hue: 0-360 degrees on color wheel
saturation: 0-100% (gray to full color)
lightness: 0-100% (black to white)
The Color Wheel
Hue degrees:
0° / 360° → Red
60° → Yellow
120° → Green
180° → Cyan
240° → Blue
300° → Magenta
HSL Examples
hsl(0, 100%, 50%) → Pure red
hsl(120, 100%, 50%) → Pure green
hsl(240, 100%, 50%) → Pure blue
hsl(0, 100%, 25%) → Dark red
hsl(0, 100%, 75%) → Light red
hsl(0, 50%, 50%) → Muted red
hsl(0, 0%, 50%) → Gray (no saturation)
HSLA for Transparency
hsla(hue, saturation, lightness, alpha)
hsla(0, 100%, 50%, 0.5) → 50% transparent red
hsla(240, 100%, 50%, 0.8) → 80% opaque blue
Comparing Formats
| Aspect | HEX | RGB | HSL |
|---|---|---|---|
| Readability | Compact | Clear values | Intuitive |
| Manipulation | Difficult | Moderate | Easy |
| Browser support | Universal | Universal | Universal |
| Common use | Brand colors | Dynamic colors | Theme systems |
| Transparency | 8-digit | rgba() | hsla() |
When to Use Each Format
Use HEX When
- Working with brand colors from design specs
- You need compact color codes
- Colors won't need manipulation
- Copying colors from design tools
Use RGB When
- Calculating colors programmatically
- Working with image data (canvas, pixel manipulation)
- Need to adjust individual color channels
- Working with color libraries
Use HSL When
- Creating color themes and variations
- Adjusting color brightness or saturation
- Building accessible color palettes
- Creating hover/active states
Color Manipulation with HSL
Creating Color Variations
// Base color
--primary: hsl(220, 80%, 50%);
// Lighter version (increase lightness)
--primary-light: hsl(220, 80%, 70%);
// Darker version (decrease lightness)
--primary-dark: hsl(220, 80%, 30%);
// Muted version (decrease saturation)
--primary-muted: hsl(220, 40%, 50%);
// Hover state (slight lightness change)
--primary-hover: hsl(220, 80%, 45%);
Creating a Color Scale
:root {
--blue-50: hsl(220, 80%, 95%);
--blue-100: hsl(220, 80%, 90%);
--blue-200: hsl(220, 80%, 80%);
--blue-300: hsl(220, 80%, 70%);
--blue-400: hsl(220, 80%, 60%);
--blue-500: hsl(220, 80%, 50%); /* Base */
--blue-600: hsl(220, 80%, 40%);
--blue-700: hsl(220, 80%, 30%);
--blue-800: hsl(220, 80%, 20%);
--blue-900: hsl(220, 80%, 10%);
}
CSS Color Functions
Modern CSS Color-Mix
/* Mix two colors */
color: color-mix(in srgb, red, blue); /* Purple */
color: color-mix(in srgb, red 70%, blue 30%);
/* Create tints and shades */
color: color-mix(in srgb, blue, white 20%); /* Lighter blue */
color: color-mix(in srgb, blue, black 20%); /* Darker blue */
Relative Colors (CSS Color Level 5)
/* Adjust existing colors */
--base: hsl(220, 80%, 50%);
/* Make it 20% lighter */
--lighter: hsl(from var(--base) h s calc(l + 20%));
/* Rotate hue by 30 degrees */
--shifted: hsl(from var(--base) calc(h + 30) s l);
Color Conversion
HEX to RGB
function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
hexToRgb("#3498DB"); // { r: 52, g: 152, b: 219 }
RGB to HEX
function rgbToHex(r, g, b) {
return "#" + [r, g, b]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}
rgbToHex(52, 152, 219); // "#3498db"
RGB to HSL
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0;
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
case g: h = ((b - r) / d + 2) / 6; break;
case b: h = ((r - g) / d + 4) / 6; break;
}
}
return {
h: Math.round(h * 360),
s: Math.round(s * 100),
l: Math.round(l * 100)
};
}
Color Accessibility
Contrast Ratios
WCAG requires minimum contrast ratios:
- Normal text: 4.5:1 (AA) or 7:1 (AAA)
- Large text: 3:1 (AA) or 4.5:1 (AAA)
- UI components: 3:1
// Calculate relative luminance
function luminance(r, g, b) {
const [rs, gs, bs] = [r, g, b].map(c => {
c /= 255;
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
});
return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
}
// Calculate contrast ratio
function contrastRatio(rgb1, rgb2) {
const l1 = luminance(...rgb1);
const l2 = luminance(...rgb2);
const lighter = Math.max(l1, l2);
const darker = Math.min(l1, l2);
return (lighter + 0.05) / (darker + 0.05);
}
Creating Accessible Palettes
// Ensure text is readable on background
function getAccessibleTextColor(bgColor) {
const rgb = hexToRgb(bgColor);
const lum = luminance(rgb.r, rgb.g, rgb.b);
return lum > 0.179 ? '#000000' : '#FFFFFF';
}
Tools and Resources
For working with colors:
- Color Converter - Convert between HEX, RGB, and HSL
- JSON Formatter - Format color configuration files
- Diff Checker - Compare color palette changes
CSS Named Colors
CSS provides 147 named colors for convenience:
/* Common named colors */
color: red; /* #FF0000 */
color: blue; /* #0000FF */
color: green; /* #008000 (not #00FF00!) */
color: lime; /* #00FF00 */
color: navy; /* #000080 */
color: teal; /* #008080 */
color: coral; /* #FF7F50 */
color: salmon; /* #FA8072 */
color: rebeccapurple; /* #663399 */
Best Practices
- Use CSS custom properties: Define colors once, use everywhere
- Choose HSL for themes: Easier to create consistent variations
- Test contrast: Always verify text readability
- Document color choices: Include semantic names (--color-error, not --red)
- Consider color blindness: Don't rely on color alone for meaning
Conclusion
Understanding color formats helps you write better CSS and create more accessible designs. Key takeaways:
- HEX is compact and universal but hard to manipulate
- RGB is clear and works well with calculations
- HSL is intuitive and perfect for creating color systems
- Always check contrast ratios for accessibility
- Use CSS custom properties for maintainable color systems
For more developer resources, explore our free online tools. For detailed specifications, see MDN CSS Color Values and WCAG Contrast Guidelines.