DEV Community

Snappy Tools
Snappy Tools

Posted on • Originally published at snappytools.app

CSS Color Formats Explained: HEX, RGB, HSL, and When to Use Each

CSS gives you four main ways to specify a colour: HEX, RGB/RGBA, HSL/HSLA, and the new Color Level 4 formats like oklch. Most developers pick one format early and stick with it everywhere — usually HEX — without thinking much about it.

But each format has genuine advantages. Here's what they are and when to reach for each one.

HEX (#RRGGBB)

The most common format. Six hexadecimal digits representing the red, green, and blue channels, each from 00 to ff.

color: #2f855a;        /* green */
color: #1a1a2e;        /* dark blue */
color: #fff;           /* white (shorthand) */
color: #000;           /* black (shorthand) */
Enter fullscreen mode Exit fullscreen mode

3-digit shorthand: When each pair of digits is identical, you can shorten it — #ff6600 becomes #f60, #ffffff becomes #fff.

With alpha (8-digit): #RRGGBBAA — the last two digits are the alpha channel.

color: #2f855a80;  /* 50% transparent green */
Enter fullscreen mode Exit fullscreen mode

When to use HEX:

  • Copying colours from Figma, Sketch, or any design tool (they output HEX by default)
  • When working from brand style guides (usually specify HEX)
  • When consistency with existing codebase is more important than readability

RGB and RGBA

Specifies red, green, and blue channels as numbers from 0 to 255, with an optional alpha from 0 to 1.

color: rgb(47, 133, 90);
color: rgba(47, 133, 90, 0.5);   /* 50% transparent */
color: rgba(0, 0, 0, 0.1);      /* 10% black overlay */
Enter fullscreen mode Exit fullscreen mode

Modern CSS also accepts the newer space-separated syntax without the function prefix:

color: rgb(47 133 90);
color: rgb(47 133 90 / 50%);    /* alpha as percentage */
Enter fullscreen mode Exit fullscreen mode

When to use RGB:

  • When alpha transparency is needed and you find rgba() more readable than 8-digit HEX
  • When you're doing colour calculations in JavaScript (canvas, getComputedStyle()) — JavaScript returns RGB values
  • When you're working with colours defined as separate channel values (common in game engines and design APIs)

HSL and HSLA

Hue, Saturation, and Lightness. A more intuitive system for humans to reason about colour.

color: hsl(145, 47%, 35%);          /* the same green as #2f855a */
color: hsl(145, 47%, 35%, 0.5);     /* 50% transparent */
color: hsl(145 47% 35% / 50%);      /* modern syntax */
Enter fullscreen mode Exit fullscreen mode

The three values:

  • Hue (H): 0°–360°, the colour wheel position (0° = red, 120° = green, 240° = blue)
  • Saturation (S): 0% = grey, 100% = fully saturated
  • Lightness (L): 0% = black, 50% = "normal", 100% = white

Why HSL is so useful for UI work:

The real power of HSL is that you can derive tints and shades by only changing the lightness value:

:root {
  --green-base: 145 47%;            /* hue + saturation */
  --green-100: hsl(var(--green-base) 95%);
  --green-200: hsl(var(--green-base) 85%);
  --green-500: hsl(var(--green-base) 50%);
  --green-700: hsl(var(--green-base) 35%);
  --green-900: hsl(var(--green-base) 20%);
}
Enter fullscreen mode Exit fullscreen mode

This produces a full colour scale from a single hue and saturation pair. Much easier to maintain than a list of HEX values.

When to use HSL:

  • Building design tokens and colour palettes
  • Generating hover states (lightness + 10%) or disabled states (lightness + 20%)
  • Darkmode: you can flip lightness values consistently
  • Any time you want the colour scale to be derived rather than hardcoded

Color Level 4: oklch() and oklab()

These are newer CSS formats that better match human colour perception. The main advantage: equal steps in the values produce visually equal differences in the rendered colour — which is not true of HSL.

color: oklch(55% 0.15 145);   /* similar to the green above */
Enter fullscreen mode Exit fullscreen mode

The three channels: Lightness (0–1), Chroma (0–0.4+), and Hue (0°–360°).

Currently supported in: Chrome 111+, Firefox 113+, Safari 15.4+. Check caniuse.com before using in production without a fallback.

Converting between formats

If you have a HEX colour from a design file and want to convert it to HSL for your CSS variables:

  1. Paste it into the Color Picker at SnappyTools — it converts between HEX, RGB, HSL, and CMYK instantly, with the eyedropper tool to sample any colour from your screen.
  2. In CSS preprocessors: Sass has color.adjust() and color.scale() functions.
  3. In JavaScript: use a colour library like chroma.js or color2k for programmatic conversions.

Quick reference

Format Opacity support Human-readable Best for
HEX 8-digit version Low Copying from design tools
RGB rgba() Medium JavaScript operations
HSL hsla() High Colour palettes, design tokens
oklch Inline Medium Perceptually uniform scales

The practical recommendation

Use HSL for your design system's colour tokens and utility classes — it's far easier to reason about and generate tints/shades programmatically. Use HEX when copying from design files or when the existing codebase uses HEX throughout. Use RGBA when you specifically need transparency and want the syntax to be explicit.

For most CSS projects, mixing formats is fine — browsers normalise everything internally. Pick whichever format is most readable in context.

Top comments (0)