BytePane

Color Formats Explained: HEX, RGB, HSL & Beyond

Design14 min read

Why Color Formats Matter for Developers

Every pixel on your screen is defined by a color value, and there are multiple ways to express that value. HEX, RGB, HSL, HSB, CMYK, and newer formats like OKLCH each serve different purposes and have different strengths. Choosing the right format affects code readability, design system flexibility, accessibility compliance, and even CSS file size.

For frontend developers, understanding color formats is not optional. You encounter them in CSS stylesheets, design tokens, Figma exports, image processing, data visualization, and accessibility audits. A misunderstanding of color math can lead to inaccessible text, inconsistent UI themes, and painful debugging sessions.

If you need to convert between color formats right now, try our Color Converter tool. It converts between HEX, RGB, HSL, and more with live preview, entirely in your browser.

HEX Colors: The Developer Standard

HEX (hexadecimal) is the most widely used color format in web development. A HEX color code starts with # followed by six hexadecimal digits representing the red, green, and blue channels. Each pair of digits ranges from 00 (0) to FF (255).

/* HEX color format */
#FF5733    /* Full 6-digit: R=FF, G=57, B=33 */
#F53      /* Shorthand 3-digit: R=FF, G=55, B=33 */
#FF573380  /* 8-digit with alpha: 80 = 50% opacity */
#F534     /* Shorthand 4-digit with alpha */

/* Common HEX values */
#000000   /* Black */
#FFFFFF   /* White */
#FF0000   /* Pure Red */
#00FF00   /* Pure Green */
#0000FF   /* Pure Blue */
#808080   /* Medium Gray */

HEX codes are case-insensitive: #ff5733 and #FF5733 are identical. The shorthand notation works when each pair consists of two identical digits: #AABBCC can be shortened to #ABC, but #FF5733 cannot be shortened because the pairs are not doubled.

HEX to RGB Conversion

// JavaScript: 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),  // FF -> 255
    g: parseInt(result[2], 16),  // 57 -> 87
    b: parseInt(result[3], 16),  // 33 -> 51
  } : null;
}

hexToRgb('#FF5733');  // { r: 255, g: 87, b: 51 }

// RGB to HEX
function rgbToHex(r, g, b) {
  return '#' + [r, g, b]
    .map(x => x.toString(16).padStart(2, '0'))
    .join('');
}

rgbToHex(255, 87, 51);  // '#ff5733'

RGB and RGBA: The Additive Color Model

RGB defines colors using three channels -- Red, Green, and Blue -- each ranging from 0 to 255. This is an additive color model: combining all three channels at full intensity produces white, while all channels at zero produces black. RGBA extends RGB with an alpha channel for transparency, ranging from 0 (fully transparent) to 1 (fully opaque).

/* CSS RGB/RGBA syntax */

/* Legacy syntax (still widely used) */
color: rgb(255, 87, 51);
background: rgba(255, 87, 51, 0.5);

/* Modern syntax (CSS Color Level 4) */
color: rgb(255 87 51);
background: rgb(255 87 51 / 0.5);
background: rgb(255 87 51 / 50%);

/* Percentage values */
color: rgb(100%, 34%, 20%);

The modern CSS Color Level 4 syntax uses spaces instead of commas and separates the alpha with a slash. Both syntaxes are supported in all modern browsers. RGB is the native format for screens, which is why it is used internally by browsers and graphics APIs regardless of what format you write in CSS.

HSL: The Human-Friendly Format

HSL represents colors using Hue, Saturation, and Lightness. Unlike RGB, which is hardware-oriented, HSL maps to how humans think about color. Want a lighter shade? Increase lightness. Want to desaturate? Decrease saturation. Want a complementary color? Add 180 to the hue.

ComponentRangeDescription
Hue (H)0-360Color wheel angle. 0=red, 120=green, 240=blue
Saturation (S)0%-100%Color intensity. 0%=gray, 100%=vivid
Lightness (L)0%-100%Brightness. 0%=black, 50%=pure color, 100%=white
/* HSL examples */
color: hsl(11, 100%, 60%);       /* Coral orange (#FF5733) */
color: hsl(11 100% 60%);         /* Modern syntax */
color: hsl(11 100% 60% / 0.5);   /* With alpha */

/* HSL makes generating variations trivial */
--color-primary:       hsl(220, 90%, 56%);    /* Base blue */
--color-primary-light: hsl(220, 90%, 70%);    /* Lighter: just +14% lightness */
--color-primary-dark:  hsl(220, 90%, 40%);    /* Darker: just -16% lightness */
--color-primary-muted: hsl(220, 30%, 56%);    /* Desaturated: just -60% saturation */
--color-complement:    hsl(40, 90%, 56%);     /* Complementary: +180 hue */

This is why HSL is the preferred format for design systems and CSS custom properties. Creating an entire color palette from a single base color requires only arithmetic on the lightness and saturation values, whereas in HEX/RGB, the same task requires complex calculations across all three channels.

Color Format Comparison

FormatExampleBest ForSupports Alpha
HEX#FF5733Code, compact notationYes (8-digit)
RGBrgb(255, 87, 51)Programmatic manipulationYes (rgba)
HSLhsl(11, 100%, 60%)Design systems, themesYes (hsla)
HSB/HSVhsb(11, 80%, 100%)Design tools (Figma, PS)Varies
OKLCHoklch(0.7 0.15 30)Perceptual uniformityYes
CMYKcmyk(0, 66, 80, 0)Print designNo

Convert between any of these formats instantly with our Color Converter tool. It handles all standard formats and shows live color previews.

Modern CSS Color Functions: OKLCH and color()

CSS Color Level 4 introduced several new color functions that solve problems with older formats. The most significant is OKLCH, which provides perceptually uniform lightness. In HSL, two colors with the same lightness value can appear visually different in brightness. OKLCH corrects this, making it the most predictable format for generating accessible color palettes.

/* OKLCH: Perceptually uniform colors */
color: oklch(0.7 0.15 30);       /* Lightness, Chroma, Hue */
color: oklch(0.7 0.15 30 / 50%); /* With alpha */

/* CSS relative color syntax (experimental) */
--base: oklch(0.6 0.2 250);
--lighter: oklch(from var(--base) calc(l + 0.2) c h);
--complementary: oklch(from var(--base) l c calc(h + 180));

/* color() function for wide-gamut displays */
color: color(display-p3 1 0.5 0);     /* P3 gamut */
color: color(srgb 1 0.34 0.2);        /* sRGB */

/* color-mix() for blending */
background: color-mix(in oklch, #FF5733 70%, white);

Browser support for OKLCH and color-mix() is now excellent, available in Chrome 111+, Firefox 113+, and Safari 16.4+. These newer formats are particularly useful for creating dark mode themes where perceptual consistency matters more than absolute color accuracy.

Accessibility and Contrast Ratios

Color accessibility is a legal requirement in many jurisdictions and a fundamental aspect of good design. The Web Content Accessibility Guidelines (WCAG) 2.1 define minimum contrast ratios between foreground text and background colors.

LevelNormal TextLarge TextUse Case
AA (Minimum)4.5:13:1Most websites, apps
AAA (Enhanced)7:14.5:1Government, healthcare

Calculating Contrast Ratio

// Calculate relative luminance (WCAG formula)
function luminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(c => {
    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 between two colors
function contrastRatio(rgb1, rgb2) {
  const l1 = luminance(rgb1.r, rgb1.g, rgb1.b);
  const l2 = luminance(rgb2.r, rgb2.g, rgb2.b);
  const lighter = Math.max(l1, l2);
  const darker = Math.min(l1, l2);
  return (lighter + 0.05) / (darker + 0.05);
}

// Example: White text on dark blue background
const ratio = contrastRatio(
  { r: 255, g: 255, b: 255 },  // White text
  { r: 30, g: 41, b: 59 }      // Dark blue background
);
console.log(ratio.toFixed(2));  // 14.72:1 (passes AAA)

Always check your color combinations against WCAG standards during design reviews. Our Color Converter can help you find accessible alternatives by adjusting lightness values while maintaining the same hue.

Building Color Palettes for Design Systems

A design system color palette typically includes a primary color, secondary colors, neutral grays, semantic colors (success, warning, error, info), and light/dark mode variants. HSL and OKLCH are the best formats for generating these palettes because they allow systematic variation of lightness and saturation.

/* Tailwind-style color scale using HSL */
:root {
  /* Blue palette from a single hue */
  --blue-50:  hsl(220, 90%, 96%);
  --blue-100: hsl(220, 90%, 90%);
  --blue-200: hsl(220, 90%, 80%);
  --blue-300: hsl(220, 90%, 70%);
  --blue-400: hsl(220, 90%, 62%);
  --blue-500: hsl(220, 90%, 56%);  /* Base */
  --blue-600: hsl(220, 90%, 48%);
  --blue-700: hsl(220, 90%, 40%);
  --blue-800: hsl(220, 90%, 30%);
  --blue-900: hsl(220, 90%, 20%);
  --blue-950: hsl(220, 90%, 12%);

  /* Semantic colors */
  --success: hsl(142, 76%, 36%);
  --warning: hsl(38, 92%, 50%);
  --error:   hsl(0, 84%, 60%);
  --info:    hsl(200, 98%, 39%);
}

/* Dark mode variant -- just adjust lightness */
[data-theme="dark"] {
  --blue-50:  hsl(220, 40%, 12%);
  --blue-100: hsl(220, 40%, 18%);
  --blue-500: hsl(220, 80%, 65%);
  --blue-900: hsl(220, 90%, 90%);
}

When working with design tokens exported from Figma, you will often receive colors in HEX format. Converting them to HSL for your CSS custom properties allows easier manipulation. Use our Color Converter to batch-convert your design tokens, and validate the CSS output with our CSS Formatter to optimize your stylesheet.

Color Conversion in Code

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);
  const l = (max + min) / 2;

  if (max === min) return { h: 0, s: 0, l: Math.round(l * 100) };

  const d = max - min;
  const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  let h;
  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),
  };
}

rgbToHsl(255, 87, 51);  // { h: 11, s: 100, l: 60 }

Python Color Conversion

import colorsys

# RGB (0-255) to HSL
r, g, b = 255, 87, 51
h, l, s = colorsys.rgb_to_hls(r/255, g/255, b/255)
print(f"hsl({h*360:.0f}, {s*100:.0f}%, {l*100:.0f}%)")
# hsl(11, 100%, 60%)

# HEX to RGB
hex_color = "#FF5733"
r = int(hex_color[1:3], 16)
g = int(hex_color[3:5], 16)
b = int(hex_color[5:7], 16)
print(f"rgb({r}, {g}, {b})")  # rgb(255, 87, 51)

Color Formats in Data Visualization

When building charts and graphs, color choices directly impact readability and accessibility. Sequential palettes use variations of a single hue (great for heatmaps), diverging palettes use two contrasting hues with a neutral midpoint (great for showing positive/negative values), and categorical palettes use distinct hues at similar saturation and lightness levels (great for comparing categories).

HSL is the best format for generating data visualization palettes because you can evenly space hues around the color wheel. For a 5-category palette, use hues at 0, 72, 144, 216, and 288 degrees with consistent saturation and lightness. OKLCH improves on this by ensuring each color appears equally vibrant to the human eye.

// Generate N evenly-spaced colors for data visualization
function generatePalette(n, saturation = 70, lightness = 55) {
  return Array.from({ length: n }, (_, i) => {
    const hue = Math.round((360 / n) * i);
    return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
  });
}

generatePalette(5);
// ['hsl(0, 70%, 55%)',   // Red
//  'hsl(72, 70%, 55%)',  // Yellow-green
//  'hsl(144, 70%, 55%)', // Green
//  'hsl(216, 70%, 55%)', // Blue
//  'hsl(288, 70%, 55%)'] // Purple

Best Practices for Working with Colors

  1. Use HSL or OKLCH for design systems -- They make generating consistent palettes, hover states, and theme variants trivial compared to HEX or RGB.
  2. Always check contrast ratios -- Test every text/background combination against WCAG 2.1 Level AA (4.5:1 minimum). Do not rely on visual inspection alone.
  3. Use CSS custom properties for colors -- Define all colors as CSS variables. This makes theme switching and dark mode implementation straightforward.
  4. Consider color blindness -- About 8% of men and 0.5% of women have some form of color vision deficiency. Never use color as the only visual indicator. Supplement with icons, labels, or patterns.
  5. Minimize your palette -- Use 1-2 primary colors, 2-4 neutral grays, and 4 semantic colors. Smaller palettes are more consistent and easier to maintain.
  6. Use named colors in code -- Instead of #1a73e8, use var(--color-primary). This improves readability and makes global changes trivial.
  7. Document your color tokens -- Maintain a living style guide that shows each color with its name, value, usage context, and minimum contrast partners.

Frequently Asked Questions

What is the difference between HEX and RGB color formats?

HEX and RGB represent the same color model -- both define colors using red, green, and blue channels. HEX uses hexadecimal notation (#FF5733) while RGB uses decimal values (rgb(255, 87, 51)). They are mathematically equivalent: each HEX pair converts to a decimal 0-255 value. HEX is more compact in code, while RGB is more intuitive when adjusting individual channel values programmatically.

Why is HSL considered better for design systems?

HSL (Hue, Saturation, Lightness) maps more closely to how humans perceive color. To create a lighter shade, you increase the lightness value. To desaturate, you decrease saturation. To shift the color, you rotate the hue. In RGB/HEX, achieving the same effect requires changing all three channels in non-intuitive ways. This makes HSL ideal for generating consistent color palettes, hover states, and theme variations.

What contrast ratio is required for web accessibility?

WCAG 2.1 requires a minimum contrast ratio of 4.5:1 for normal text (Level AA) and 7:1 for enhanced contrast (Level AAA). Large text (18px bold or 24px regular) has a lower requirement of 3:1 for Level AA. These ratios ensure text is readable by people with moderate visual impairments, including color vision deficiency.

Convert Colors Instantly

Paste any HEX, RGB, or HSL value into our free Color Converter and get all formats instantly with live color preview. No signup, no data collection, everything runs in your browser.

Open Color Converter

Related Articles