·10 min read

CSS Color Formats Explained: HEX, RGB, HSL and More

CSS offers a rich variety of color formats, each with different strengths. Whether you are tweaking a design system or building an accessible UI, understanding these formats helps you pick the right one for every situation. This guide walks through every major CSS color format with practical examples and conversion tips.

CSS Color Formats at a Glance

Modern CSS supports more color formats than most developers realize. At the most basic level, you can use named keywords like red or cornflowerblue. For precise control, HEX codes, RGB, and HSL have been the workhorses of web design for decades. And with CSS Color Level 4, new formats like oklch and functions like color-mix() give designers even finer control over color perception and blending.

Here is a quick comparison of the most common formats:

FormatExampleAlpha Support
HEX#3b82f6Yes (8-digit)
RGB / RGBArgb(59 130 246)Yes
HSL / HSLAhsl(217 91% 60%)Yes
NameddodgerblueNo
OKLCHoklch(0.7 0.15 250)Yes

HEX Colors: The Web's Most Popular Format

HEX (hexadecimal) color codes are arguably the most widely used color format on the web. A HEX code starts with a # followed by hexadecimal digits representing the red, green, and blue channels. Each channel ranges from 00 (0) to FF (255).

3-Digit Shorthand

When each pair of digits is identical, you can shorten a 6-digit HEX to 3 digits. For example, #ff6600 becomes #f60, and #ffffff becomes #fff. This saves a few bytes and is common in minified stylesheets.

6-Digit Standard

The standard 6-digit format gives you full control over 16.7 million possible colors. This is what most design tools export by default and what you will encounter in the vast majority of CSS codebases.

.button {
  background-color: #3b82f6;  /* Blue */
  color: #ffffff;              /* White */
  border-color: #1e40af;      /* Darker blue */
}

8-Digit HEX with Alpha

The 8-digit HEX format appends two extra digits for the alpha (opacity) channel. For example, #3b82f680 is the same blue at 50% opacity (80 in hex equals 128, which is roughly 50% of 255). While supported in all modern browsers, many developers find the alpha channel hard to read in hex and prefer RGBA or HSLA instead.

RGB and RGBA: Channel-Based Control

The RGB format specifies colors using red, green, and blue channel values from 0 to 255. Modern CSS syntax uses space-separated values inside the rgb() function, with an optional alpha value separated by a slash:

/* Modern syntax (recommended) */
color: rgb(59 130 246);
color: rgb(59 130 246 / 0.5);    /* 50% opacity */

/* Legacy syntax (still works) */
color: rgba(59, 130, 246, 0.5);

RGB is intuitive when you think in terms of light mixing: 0 is no light and 255 is full intensity. However, it can be difficult to predict what a color looks like just by reading the numbers. Knowing that rgb(59 130 246) is blue requires familiarity or a reference chart. This is where HSL shines.

HSL and HSLA: The Most Human-Friendly Format

HSL stands for Hue, Saturation, and Lightness. It maps directly to how humans think about color, making it far more intuitive than RGB for tasks like creating color palettes or adjusting brightness.

  • Hue (0-360): The color wheel position. 0 is red, 120 is green, 240 is blue. Think of it as an angle on a circle.
  • Saturation (0-100%): How vivid the color is. 0% is completely gray, 100% is fully saturated.
  • Lightness (0-100%): How light or dark. 0% is black, 50% is the pure hue, 100% is white.
/* A vibrant blue */
color: hsl(217 91% 60%);

/* Same blue at 50% opacity */
color: hsl(217 91% 60% / 0.5);

/* Create a lighter variant - just increase lightness */
color: hsl(217 91% 80%);

/* Create a muted variant - just decrease saturation */
color: hsl(217 30% 60%);

The real power of HSL is how easy it is to create consistent color systems. Want a darker shade? Decrease lightness. Want a pastel version? Increase lightness and decrease saturation. Want a complementary color? Add 180 to the hue. With RGB or HEX, these operations require calculating all three channels independently, which is far less intuitive.

CSS Named Colors

CSS defines 148 named color keywords ranging from the obvious (red, blue, green) to the exotic (papayawhip, rebeccapurple, lemonchiffon). These names originate from the X11 color system and early HTML specifications.

Named colors are excellent for prototyping, debugging (a quick border: 2px solid red to visualize an element), and readable code where exact color precision does not matter. However, they do not support alpha transparency and offer limited coverage of the color spectrum, so production design systems typically use HEX, RGB, or HSL instead.

Special mention goes to transparent (equivalent to rgba(0,0,0,0)) and currentColor, which inherits the element's text color and is incredibly useful for SVG icons and border styling.

Modern CSS Color Functions

OKLCH: Perceptually Uniform Colors

OKLCH is a newer color space that aims for perceptual uniformity — meaning that changing the lightness value by the same amount always looks like the same degree of change to the human eye, regardless of hue. This is not true for HSL, where a 10% lightness shift on yellow looks very different from the same shift on blue.

/* oklch(lightness chroma hue) */
color: oklch(0.7 0.15 250);       /* A blue */
color: oklch(0.7 0.15 150);       /* A green with same perceived lightness */
color: oklch(0.7 0.15 30);        /* An orange with same perceived lightness */

OKLCH is especially valuable for design systems because you can create entire palettes where all colors at the same lightness value genuinely look equally bright. All modern browsers now support OKLCH.

color-mix(): Blending Colors in CSS

The color-mix() function lets you blend two colors together directly in CSS, without preprocessors like Sass. This is powerful for creating hover states, disabled styles, and dynamic theming.

/* Mix blue and white to get a lighter blue */
background: color-mix(in srgb, #3b82f6, white 30%);

/* Mix in oklch for perceptually balanced results */
background: color-mix(in oklch, #3b82f6, white 30%);

/* Great for hover states */
.button:hover {
  background: color-mix(in srgb, var(--brand-color), black 15%);
}

Relative Color Syntax

CSS now also supports relative color syntax, allowing you to derive a new color from an existing one by adjusting individual channels. This eliminates the need for CSS custom property hacks or JavaScript calculations for simple color modifications:

/* Take a color and make it 20% lighter */
color: hsl(from var(--brand) h s calc(l + 20%));

/* Desaturate a color */
color: hsl(from var(--brand) h calc(s - 30%) l);

Color Accessibility and WCAG Contrast Standards

Choosing colors is not just about aesthetics. The Web Content Accessibility Guidelines (WCAG) define minimum contrast ratios to ensure text remains readable for users with visual impairments. Getting this right is both a legal requirement in many jurisdictions and simply good design practice.

  • WCAG AA (minimum): Normal text requires a contrast ratio of at least 4.5:1 against its background. Large text (18px bold or 24px regular) requires at least 3:1.
  • WCAG AAA (enhanced): Normal text requires 7:1, large text requires 4.5:1. This level is recommended for long-form content.
  • Non-text contrast: UI components like buttons, input borders, and icons require at least 3:1 contrast against adjacent colors.

The contrast ratio formula compares the relative luminance of two colors. Luminance is calculated from the RGB values, not from HSL lightness. Two colors with identical HSL lightness can have very different luminance values (yellow versus blue, for example). This is another area where OKLCH excels, because its lightness correlates much better with perceived brightness.

Always test your color choices with a contrast checker. Avoid relying on color alone to convey information — use icons, patterns, or text labels as well, since roughly 8% of men and 0.5% of women have some form of color vision deficiency.

Color Format Conversion Methods

Converting between color formats is a common task. Here are practical code snippets for the most frequent conversions:

HEX to RGB (JavaScript)

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

hexToRgb('#3b82f6'); // { r: 59, g: 130, b: 246 }

RGB to HSL (JavaScript)

function rgbToHsl(r, g, b) {
  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) };
}

rgbToHsl(59, 130, 246); // { h: 217, s: 91, l: 60 }

CSS Native Conversion

Modern browsers can handle format conversion natively. You can set a color in any format and the browser computes the equivalent in other formats. The getComputedStyle() API always returns colors in RGB format, giving you a quick programmatic conversion:

// Set any color format and read back as RGB
element.style.color = 'hsl(217 91% 60%)';
const rgb = getComputedStyle(element).color;
// Returns: "rgb(59, 130, 246)"

Which Format Should You Use?

  • Design handoff: Use HEX. Designers and tools like Figma communicate in HEX by default, and it is the most compact format for opaque colors.
  • Dynamic theming: Use HSL or OKLCH with CSS custom properties. Adjusting individual channels (lightness, saturation) is trivial and enables powerful theme variations.
  • Transparency: Use RGB or HSL with alpha. The slash syntax (rgb(59 130 246 / 0.5)) is clean and readable.
  • Perceptual consistency: Use OKLCH for design systems where colors at the same lightness level must look equally bright across all hues.
  • Quick prototyping: Use named colors. Nothing beats border: 2px solid tomato for speed.

Related Tools

Try these free online tools to work with CSS colors more efficiently:

Try These Tools

Need a form backend for your project?

FormCatch handles form submissions so you don't have to. Free tier included.

Try FormCatch Free →
Support us$3$5$10