ToolPopToolPop
Back to BlogTutorials

Color Converter Guide: HEX, RGB, HSL, and Beyond for Developers

Colors in web development come in many formats. Learn to convert between HEX, RGB, HSL and understand when to use each format.

ToolPop TeamMarch 15, 202513 min read

Understanding Color Formats

Web developers work with colors in multiple formats. Each has its strengths and ideal use cases. Let's master them all.

Color Format Overview

HEX (Hexadecimal)

The most common format in web development:

/* 6-digit HEX */
color: #FF5733;

/* 3-digit shorthand (when digits repeat) */
color: #F00;  /* Same as #FF0000 */

/* 8-digit with alpha */
color: #FF573380;  /* 50% opacity */

Structure: #RRGGBB or #RRGGBBAA

  • RR: Red (00-FF)
  • GG: Green (00-FF)
  • BB: Blue (00-FF)
  • AA: Alpha (00-FF)

RGB/RGBA

Red, Green, Blue values (0-255):

/* RGB */
color: rgb(255, 87, 51);

/* RGBA with opacity */
color: rgba(255, 87, 51, 0.5);

/* Modern syntax */
color: rgb(255 87 51);
color: rgb(255 87 51 / 50%);

HSL/HSLA

Hue, Saturation, Lightness:

/* HSL */
color: hsl(11, 100%, 60%);

/* HSLA with opacity */
color: hsla(11, 100%, 60%, 0.5);

/* Modern syntax */
color: hsl(11 100% 60% / 50%);

Structure:

  • Hue: 0-360 (color wheel degree)
  • Saturation: 0%-100% (gray to vivid)
  • Lightness: 0%-100% (black to white)

HSB/HSV

Hue, Saturation, Brightness (used in design tools):

H: 11°
S: 80%
B: 100%

Note: CSS doesn't support HSB natively. Convert to HSL for web use.

Color Conversion Formulas

HEX to RGB

function hexToRgb(hex) {
  // Remove # if present
  hex = hex.replace('#', '');

  // Handle 3-digit shorthand
  if (hex.length === 3) {
    hex = hex.split('').map(c => c + c).join('');
  }

  const r = parseInt(hex.substring(0, 2), 16);
  const g = parseInt(hex.substring(2, 4), 16);
  const b = parseInt(hex.substring(4, 6), 16);

  return { r, g, b };
}

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

RGB to HEX

function rgbToHex(r, g, b) {
  const toHex = n => n.toString(16).padStart(2, '0');
  return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

// Usage
rgbToHex(255, 87, 51);  // "#ff5733"

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)
  };
}

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

HSL to RGB

function hslToRgb(h, s, l) {
  h /= 360;
  s /= 100;
  l /= 100;

  let r, g, b;

  if (s === 0) {
    r = g = b = l;
  } else {
    const hue2rgb = (p, q, t) => {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1/6) return p + (q - p) * 6 * t;
      if (t < 1/2) return q;
      if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
      return p;
    };

    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;

    r = hue2rgb(p, q, h + 1/3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1/3);
  }

  return {
    r: Math.round(r * 255),
    g: Math.round(g * 255),
    b: Math.round(b * 255)
  };
}

When to Use Each Format

HEX

Best for:

  • Design specifications from Figma/Sketch
  • Quick color definitions
  • When you know the exact color
/* Common use */
.button {
  background-color: #3498db;
  border-color: #2980b9;
}

RGB/RGBA

Best for:

  • When you need transparency
  • Programmatic color manipulation
  • Working with color values as numbers
/* Overlay with transparency */
.overlay {
  background-color: rgba(0, 0, 0, 0.5);
}

HSL/HSLA

Best for:

  • Creating color variations
  • Theming systems
  • Accessible color contrast
/* Easy color variations */
:root {
  --primary-h: 220;
  --primary-s: 90%;
  --primary-l: 50%;
}

.primary {
  background: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}

.primary-light {
  /* Just change lightness */
  background: hsl(var(--primary-h), var(--primary-s), 70%);
}

.primary-dark {
  background: hsl(var(--primary-h), var(--primary-s), 30%);
}

CSS Color Functions (Modern)

color-mix()

Mix two colors:

.mixed {
  background: color-mix(in srgb, #ff0000 50%, #0000ff);
  /* Results in purple */
}

Relative Colors

Modify existing colors:

:root {
  --brand: #3498db;
}

.lighter {
  /* Make 20% lighter */
  background: hsl(from var(--brand) h s calc(l + 20%));
}

oklch() and oklab()

Perceptually uniform color spaces:

.modern {
  /* L: lightness, C: chroma, H: hue */
  background: oklch(70% 0.15 250);
}

Color Manipulation Techniques

Darken/Lighten

function adjustLightness(hex, percent) {
  const { r, g, b } = hexToRgb(hex);
  const { h, s, l } = rgbToHsl(r, g, b);

  const newL = Math.max(0, Math.min(100, l + percent));
  const { r: nr, g: ng, b: nb } = hslToRgb(h, s, newL);

  return rgbToHex(nr, ng, nb);
}

// Lighten by 20%
adjustLightness('#3498db', 20);  // "#7ab8e8"

// Darken by 20%
adjustLightness('#3498db', -20); // "#1d6fa5"

Saturate/Desaturate

function adjustSaturation(hex, percent) {
  const { r, g, b } = hexToRgb(hex);
  const { h, s, l } = rgbToHsl(r, g, b);

  const newS = Math.max(0, Math.min(100, s + percent));
  const { r: nr, g: ng, b: nb } = hslToRgb(h, newS, l);

  return rgbToHex(nr, ng, nb);
}

Complementary Color

function complementary(hex) {
  const { r, g, b } = hexToRgb(hex);
  const { h, s, l } = rgbToHsl(r, g, b);

  // Add 180° to hue
  const newH = (h + 180) % 360;
  const { r: nr, g: ng, b: nb } = hslToRgb(newH, s, l);

  return rgbToHex(nr, ng, nb);
}

complementary('#3498db');  // "#db7434"

Analogous Colors

function analogous(hex) {
  const { r, g, b } = hexToRgb(hex);
  const { h, s, l } = rgbToHsl(r, g, b);

  return [
    hslToHex((h - 30 + 360) % 360, s, l),
    hex,
    hslToHex((h + 30) % 360, s, l)
  ];
}

Accessibility and Contrast

WCAG Contrast Requirements

LevelNormal TextLarge Text
AA4.5:13:1
AAA7:14.5:1

Calculate Contrast Ratio

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;
}

function contrastRatio(hex1, hex2) {
  const rgb1 = hexToRgb(hex1);
  const rgb2 = hexToRgb(hex2);

  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);
}

// Check accessibility
contrastRatio('#000000', '#ffffff');  // 21:1 (perfect)
contrastRatio('#3498db', '#ffffff');  // 2.79:1 (fails AA)

Color Systems in CSS

CSS Custom Properties

:root {
  /* Base colors */
  --color-primary: #3498db;
  --color-secondary: #2ecc71;
  --color-accent: #e74c3c;

  /* Semantic colors */
  --color-success: var(--color-secondary);
  --color-error: var(--color-accent);
  --color-warning: #f39c12;

  /* Shades */
  --color-primary-light: #5faee3;
  --color-primary-dark: #217dbb;
}

/* Usage */
.button {
  background-color: var(--color-primary);
}

.button:hover {
  background-color: var(--color-primary-dark);
}

Tailwind-style Scale

:root {
  --blue-50: #eff6ff;
  --blue-100: #dbeafe;
  --blue-200: #bfdbfe;
  --blue-300: #93c5fd;
  --blue-400: #60a5fa;
  --blue-500: #3b82f6;
  --blue-600: #2563eb;
  --blue-700: #1d4ed8;
  --blue-800: #1e40af;
  --blue-900: #1e3a8a;
}

Common Color Issues

Issue 1: Colors Look Different

Same HEX can look different due to:

  • Monitor calibration
  • Color profiles (sRGB vs P3)
  • Browser rendering

Issue 2: Opacity Stacking

/* Overlapping transparent elements */
.overlay1 {
  background: rgba(0, 0, 0, 0.5);
}
.overlay2 {
  /* On top of overlay1, this isn't 75% opaque total */
  background: rgba(0, 0, 0, 0.5);
}

Issue 3: Color Space Clipping

Wide-gamut displays can show more colors than sRGB:

/* Use Display P3 when available */
.vibrant {
  background: color(display-p3 1 0.2 0.1);
}

Conclusion

Understanding color formats helps you write better CSS, create accessible designs, and build robust theming systems. Use HEX for quick definitions, RGBA for transparency, and HSL for programmatic color manipulation.

Use our free Color Converter tool to quickly convert between formats during development and design work.

Tags
color converterhex to rgbrgb to hslcolor pickercss colorscolor formatweb colors
Share this article

Try Our Free Tools

Put these tips into practice with our free online tools. No signup required.

Explore Tools