Developer's Guide to Color Formats: HEX, RGB, HSL, and More

Web colors can be expressed in many formats — HEX, RGB, HSL, oklch, and more. Each format has strengths that make it appropriate for different use cases. Understanding them helps you write more maintainable CSS and work effectively with design tools.

Named Colors

HEX is what designers export, HSL is what you actually want to write by hand, and oklch is what you'd use if you were starting a project today. Most codebases use all three for different reasons — HEX because Figma spits it out, HSL because it's easy to reason about lightness and saturation, and oklch because it finally makes perceptually consistent color scales possible without manual tuning.

color: red;
color: forestgreen;       /* #228B22 */
color: cornflowerblue;    /* #6495ED */
color: rebeccapurple;     /* #663399 */
color: transparent;       /* rgba(0,0,0,0) */

Named colors are useful for quick prototyping and readable code where the exact shade doesn't matter. Use them in development; replace with precise values in production.

HEX Colors

Hexadecimal color notation is the most common format for web development, especially when working with design tools. Each color channel (red, green, blue) is expressed as a two-digit hexadecimal number (00–FF), representing 0–255.

#RRGGBB

#FF0000   /* red:   R=255, G=0, B=0 */
#00FF00   /* green: R=0, G=255, B=0 */
#0000FF   /* blue:  R=0, G=0, B=255 */
#6366f1   /* indigo (lowercase is fine) */
#000000   /* black */
#FFFFFF   /* white */

HEX Shorthand

When both digits of each channel are identical, you can use a 3-character shorthand. #RGB expands to #RRGGBB by doubling each digit:

#F00  =  #FF0000  /* red */
#0F0  =  #00FF00  /* green */
#FFF  =  #FFFFFF  /* white */
#333  =  #333333  /* dark gray */

HEX with Alpha: #RRGGBBAA

Modern CSS supports 8-digit HEX for alpha transparency. The last two digits represent the alpha channel (00 = fully transparent, FF = fully opaque):

#6366f180   /* indigo at 50% opacity */
#00000040   /* black at 25% opacity */
#ffffff00   /* white fully transparent */

RGB and RGBA

RGB represents colors as three decimal values (0–255) for red, green, and blue channels. RGBA adds an alpha channel (0 = transparent, 1 = opaque).

rgb(255, 0, 0)            /* red */
rgb(99, 102, 241)         /* indigo */
rgba(99, 102, 241, 0.5)   /* indigo at 50% opacity */

/* Modern space-separated syntax (CSS Color Level 4) */
rgb(99 102 241)
rgb(99 102 241 / 50%)     /* alpha as percentage */
rgb(99 102 241 / 0.5)     /* alpha as decimal */

RGB is useful when you need to compute or manipulate color values programmatically — it's easy to extract individual channels, and many color manipulation libraries work in RGB space.

HSL and HSLA: The Human-Friendly Format

HSL (Hue, Saturation, Lightness) is often more intuitive for developers and designers because it separates the three perceptual attributes of color:

  • Hue: The color itself, expressed as a degree on the color wheel (0°=red, 120°=green, 240°=blue, 360°=red again)
  • Saturation: How vivid the color is, from 0% (gray) to 100% (fully saturated)
  • Lightness: How light or dark, from 0% (black) to 100% (white), with 50% being the pure color
hsl(0, 100%, 50%)         /* red */
hsl(120, 100%, 50%)       /* green */
hsl(240, 100%, 50%)       /* blue */
hsl(262, 83%, 67%)        /* indigo (#6366f1 equivalent) */
hsla(262, 83%, 67%, 0.5)  /* 50% opacity */

/* Modern syntax */
hsl(262 83% 67% / 50%)

HSL excels at creating color palettes. To create lighter or darker variants of a color, just adjust the lightness. To create a muted version, reduce the saturation. This makes it far easier to design consistent color systems than with HEX or RGB.

/* Creating a color palette with HSL */
--blue-100: hsl(221, 91%, 95%);   /* very light */
--blue-300: hsl(221, 91%, 75%);
--blue-500: hsl(221, 91%, 55%);   /* base color */
--blue-700: hsl(221, 91%, 35%);
--blue-900: hsl(221, 91%, 15%);   /* very dark */

Modern Color Spaces: oklch and oklabf

CSS Color Level 4 introduced perceptually uniform color spaces that better match how humans perceive color differences. The key issue with sRGB (which HEX/RGB/HSL all use): equal steps in numeric values don't produce equal-looking perceptual differences.

oklch (Lightness, Chroma, Hue in the Oklab color space) is emerging as the preferred format for modern design systems:

/* oklch(Lightness Chroma Hue) */
oklch(0.63 0.17 264)    /* indigo */
oklch(0.80 0.12 264)    /* lighter indigo (more predictable) */
oklch(0.40 0.17 264)    /* darker indigo */

/* With alpha */
oklch(0.63 0.17 264 / 50%)

With oklch, adjusting lightness produces perceptually consistent results across different hues — something HSL fails at (yellow and blue look very different at the same HSL lightness value). Browser support is now excellent (all modern browsers).

Converting Between Formats

All modern browsers accept any color format in CSS, but you'll frequently need to convert between them for design tools, APIs, or legacy code:

// 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),
    g: parseInt(result[2], 16),
    b: parseInt(result[3], 16)
  } : null;
}

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

// Using browser's built-in parsing
const div = document.createElement('div');
div.style.color = 'cornflowerblue';
document.body.appendChild(div);
getComputedStyle(div).color; // 'rgb(100, 149, 237)'

When to Use Each Format

  • HEX: Copy-pasting from design tools (Figma, Sketch), working with a defined color palette, most common in codebases.
  • RGB/RGBA: Dynamic color manipulation in JavaScript, working with canvas or WebGL, when you need to pass color channels as separate values.
  • HSL/HSLA: Building design systems, creating color variations programmatically, making colors more readable in CSS.
  • oklch: Modern design systems requiring perceptually consistent color scales, HDR displays, new projects targeting evergreen browsers.
  • Named colors: Prototyping, tests, debugging, or when semantics matter more than precision.
CSS Custom Properties + HSL = Powerful Theming

Combining CSS custom properties with HSL enables elegant theming. Define your base hue as a variable, then construct all color variants from it. Changing a single hue value shifts your entire color scheme: --hue: 262; --accent: hsl(var(--hue) 83% 67%);. This pattern makes it trivial to implement multiple themes or even user-selected accent colors.

Conclusion

Understanding all web color formats gives you the flexibility to work effectively with any tool or codebase. HEX is the lingua franca of web colors — familiar, compact, and universally supported. HSL is the developer's color format — intuitive, easy to manipulate, and excellent for design systems. Modern projects should consider oklch for perceptually uniform color palettes. Regardless of format, CSS accepts them all, so you can choose the format that best fits the context and readability needs of your code.