The definitive guide to color format conversion for web designers and developers
Color is one of the most powerful tools in a web designer's arsenal. It conveys mood, establishes brand identity, guides user attention, and affects readability. But behind every visually striking website lies a precise system for defining and reproducing colors consistently across different devices and browsers.
The two most widely used color formats in web development are HEX (hexadecimal) and RGB (red, green, blue). While they represent the same colors, they do so in different notations, and knowing how to convert between them is an essential skill. This guide will walk you through the theory, the math, the code, and the practical considerations.
HEX color codes use hexadecimal notation to define colors. A standard HEX color code is a string starting with # followed by six hexadecimal digits, representing the red, green, and blue components in that order.
The format is #RRGGBB, where each pair of hexadecimal digits represents one color channel:
| Color | HEX | RGB | Preview |
|---|---|---|---|
| Red | #FF0000 | rgb(255, 0, 0) | |
| Green | #00FF00 | rgb(0, 255, 0) | |
| Blue | #0000FF | rgb(0, 0, 255) | |
| White | #FFFFFF | rgb(255, 255, 255) | |
| Black | #000000 | rgb(0, 0, 0) | |
| Coral | #FF7F50 | rgb(255, 127, 80) |
HEX also supports a shorthand notation: #RGB where each digit is duplicated (#F00 = #FF0000). This works when each pair has identical digits, which is common for "pure" colors but less useful for subtle shades.
Modern CSS also supports 8-digit HEX codes with an alpha channel: #RRGGBBAA (e.g., #FF000080 for 50% transparent red). The alpha value follows the same 0x00–0xFF range, where 0x00 is fully transparent and 0xFF is fully opaque.
RGB stands for Red, Green, Blue — the three primary colors of light. In the RGB model, colors are created by combining these three channels at different intensities, typically ranging from 0 to 255.
In CSS, RGB colors are expressed using the rgb() function:
/* CSS RGB examples */
background-color: rgb(255, 87, 51); /* Solid color */
background-color: rgba(255, 87, 51, 0.5); /* 50% transparent */
background-color: rgb(255 87 51 / 0.5); /* Modern syntax (CSS Colors Level 4) */
The RGB model is additive: combining all three channels at full intensity produces white (rgb(255, 255, 255)), while setting all to zero produces black (rgb(0, 0, 0)). This is fundamentally different from the subtractive color model used in print (CMYK).
While HEX and RGB define colors by channel intensity, HSL (Hue, Saturation, Lightness) defines them more intuitively:
/* HSL examples */
color: hsl(9, 100%, 60%); /* Vivid red-orange */
color: hsl(210, 80%, 50%); /* Rich blue */
color: hsl(0, 0%, 50%); /* Medium gray */
HSL is often preferred for creating color palettes because adjusting lightness or saturation is more intuitive than tweaking individual RGB values. CSS Colors Level 4 also introduced hwb() (Hue, Whiteness, Blackness) and oklch(), which offer perceptually uniform color spaces.
The conversion from HEX to RGB is a straightforward base-16 to base-10 conversion for each color channel.
Take #FF7F50 (coral) as an example:
FF, 7F, 50FF = 15×16 + 15 = 255 (red)7F = 7×16 + 15 = 127 (green)50 = 5×16 + 0 = 80 (blue)rgb(255, 127, 80)The reverse process converts each decimal value (0–255) to a two-digit hexadecimal string:
# prefixrgb(65, 131, 215) to HEX:4183D7#4183D7
// 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;
}
// RGB to HEX
function rgbToHex(r, g, b) {
return '#' + [r, g, b].map(x => {
const hex = x.toString(16);
return hex.length === 1 ? '0' + hex : hex;
}).join('');
}
// HEX to HSL
function hexToHsl(hex) {
let { r, g, b } = hexToRgb(hex);
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b), 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) };
}
# HEX to RGB
def hex_to_rgb(hex_color):
hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
# RGB to HEX
def rgb_to_hex(r, g, b):
return f'#{r:02x}{g:02x}{b:02x}'
# Examples
print(hex_to_rgb('#FF7F50')) # (255, 127, 80)
print(rgb_to_hex(255, 127, 80)) # '#ff7f50'
/* CSS now supports color-mix() for blending */
color-mix(in srgb, #ff7f50 50%, #4183d7 50%);
/* Relative color syntax (CSS Colors Level 4) */
--accent: #ff7f50;
--lighter: rgb(from var(--accent) r g b / 0.5);
--desaturated: hsl(from var(--accent) h 50% l);
Use a consistent format in your codebase. Pick one format (HEX or RGB) and stick with it throughout a project. Mixing formats makes the code harder to scan and maintain. Most teams default to HEX for its compactness, but RGB or HSL can be clearer when you need to adjust individual channels.
Use CSS custom properties for design tokens. Define your color palette as CSS variables, which makes theme switching and maintenance trivial:
:root {
--color-primary: #4183D7;
--color-secondary: #FF7F50;
--color-surface: #F8F9FA;
--color-text: #1A1A2E;
}
Design in HSL, ship in HEX or RGB. HSL is more intuitive for creating harmonious palettes (adjusting lightness for hover states, desaturating for muted variants), but convert to HEX or RGB for the final stylesheet.
Test across devices. Color rendering varies between monitors, operating systems, and browsers. Always preview your palette on multiple screens, and consider using oklch() for perceptually uniform colors in modern browsers.
Color choice directly impacts accessibility. Approximately 8% of men and 0.5% of women have some form of color vision deficiency. To ensure your designs are accessible:
Convert colors instantly between HEX, RGB, HSL, and more. Includes a live preview and accessibility checker.
Open HEX to RGB Converter →