Overview of CSS Color Formats
CSS supports a rich variety of color formats, each with different strengths. Understanding when to use hex, rgb(), rgba(), hsl(), hsla(), oklch(), named colors, currentColor, and color-mix() will make your stylesheets more maintainable, readable, and visually consistent.
Let's walk through each format, understand how it works, and when to reach for it.
Hex Colors (#rrggbb)
Hexadecimal is the most common color format on the web. A hex color is a 6-digit code where pairs of digits represent red, green, and blue channels in base-16 (0–FF).
/* Standard 6-digit hex */
color: #ff5733; /* red=ff, green=57, blue=33 */
color: #000000; /* black */
color: #ffffff; /* white */
/* 3-digit shorthand (when both digits of each pair are identical) */
color: #f53; /* same as #ff5533 */
color: #000; /* same as #000000 */
/* 8-digit hex with alpha (last two digits = opacity) */
color: #ff573380; /* 50% opacity */
When to use hex: Design handoffs, copying colors from tools like Figma, brand color palettes. It's compact and universally supported. The 8-digit hex with alpha is less readable than rgba(), so use it sparingly.
rgb() and rgba()
The rgb() function defines colors with red, green, and blue values from 0–255. rgba() adds an alpha (transparency) channel from 0 (invisible) to 1 (opaque).
/* rgb — no transparency */
color: rgb(255, 87, 51);
/* rgba — with transparency */
background-color: rgba(0, 0, 0, 0.5); /* 50% black overlay */
background-color: rgba(255, 255, 255, 0.1); /* subtle white tint */
/* Modern space-separated syntax (CSS Color Level 4) */
color: rgb(255 87 51);
color: rgb(255 87 51 / 50%); /* alpha as percentage */
When to use rgba(): Overlays, semi-transparent backgrounds, text shadows, and anywhere you need transparency without affecting child elements (unlike opacity, which affects children).
hsl() and hsla()
HSL stands for Hue, Saturation, Lightness. This format is the most human-readable because it maps closely to how we actually think about colors.
- Hue — A degree on the color wheel (0–360). 0=red, 120=green, 240=blue.
- Saturation — Intensity of the color (0% = gray, 100% = full color)
- Lightness — Brightness (0% = black, 50% = normal, 100% = white)
/* hsl */
color: hsl(14, 100%, 60%); /* a warm orange-red */
color: hsl(210, 80%, 50%); /* a vivid blue */
/* hsla — with transparency */
background: hsla(210, 80%, 50%, 0.3);
/* Create a color palette by varying lightness */
--color-100: hsl(220, 90%, 95%);
--color-200: hsl(220, 90%, 85%);
--color-500: hsl(220, 90%, 50%); /* base color */
--color-700: hsl(220, 90%, 35%);
--color-900: hsl(220, 90%, 20%);
When to use hsl(): Building color systems, creating tints and shades programmatically, theming. The lightness axis makes it trivial to generate accessible color palettes — just keep the hue and saturation constant while varying lightness.
oklch() — The Modern Standard
oklch() is the newest and most perceptually uniform color format in CSS. It stands for OK Lab Chroma Hue and is part of CSS Color Level 4.
- L — Perceptual lightness (0–1)
- C — Chroma (color intensity, 0–0.4+)
- H — Hue angle (0–360)
/* oklch syntax */
color: oklch(0.65 0.2 250); /* a vivid blue */
color: oklch(0.8 0.15 120); /* a soft green */
/* With alpha */
color: oklch(0.5 0.3 30 / 0.8);
/* Creating a perceptually uniform gradient — colors appear equally vibrant */
.gradient {
background: linear-gradient(
to right,
oklch(0.6 0.2 0), /* red */
oklch(0.6 0.2 120), /* green */
oklch(0.6 0.2 240) /* blue */
);
}
Unlike HSL, oklch produces colors that are perceptually uniform — two colors with the same lightness value actually look equally bright to the human eye. HSL's lightness is mathematically equal but visually uneven (a yellow at L=50% looks much brighter than a blue at L=50%).
When to use oklch(): Modern design systems, accessible color palettes, gradients, any project targeting up-to-date browsers (Chrome 111+, Firefox 113+, Safari 15.4+). Use our Gradient Generator to experiment with oklch gradients visually.
Named Colors
CSS has 148 named colors — from red and blue to rebeccapurple and cornflowerblue. They're great for quick prototyping but not ideal for production code where precise brand colors matter.
/* Named colors */
color: red;
color: dodgerblue;
color: tomato;
color: rebeccapurple; /* named after Eric Meyer's daughter Rebecca */
color: transparent; /* fully transparent */
color: currentColor; /* inherits the element's current text color */
currentColor — The Underrated Keyword
currentColor is one of CSS's most useful keywords. It represents the current color property value and can be used anywhere a color is accepted. It makes icon SVGs, borders, and box shadows automatically match surrounding text.
.icon-button {
color: var(--accent);
border: 2px solid currentColor; /* border matches text color */
}
.icon-button svg {
fill: currentColor; /* SVG fills match text color too */
}
/* On hover, changing color cascades to border and SVG */
.icon-button:hover {
color: var(--accent-dark);
}
color-mix() — Mixing Colors in CSS
The color-mix() function lets you blend two colors directly in CSS without JavaScript. It was introduced in CSS Color Level 5 and is supported in all modern browsers.
/* Mix 40% red with 60% blue in sRGB color space */
color: color-mix(in srgb, red 40%, blue);
/* Create a lighter version of a custom property */
--brand: oklch(0.5 0.3 250);
--brand-light: color-mix(in oklch, var(--brand), white 40%);
--brand-dark: color-mix(in oklch, var(--brand), black 30%);
/* Semi-transparent variant */
--brand-alpha: color-mix(in srgb, var(--brand) 50%, transparent);
color-mix() is a game-changer for theming. You can define one brand color and generate all its variants dynamically — no preprocessor needed.
Choosing the Right Format: A Practical Guide
Use hex when:
- You're copying colors from a design tool (Figma, Photoshop)
- Working with fixed brand colors that never need manipulation
- You want compact, widely recognized notation
Use rgba() when:
- You need transparency without affecting child elements
- Applying overlays, shadows, or glass-morphism effects
Use hsl() when:
- Building a color system with predictable tints/shades
- Working with CSS custom properties that are easy to read
- You want to understand the color without decoding hex
Use oklch() when:
- Building perceptually accessible color palettes
- Creating smooth, vibrant gradients
- Working on modern design systems targeting current browsers
Practical Example: A Complete Color System
:root {
/* Brand color defined in oklch for perceptual uniformity */
--brand-500: oklch(0.55 0.28 265);
/* Variants using color-mix */
--brand-100: color-mix(in oklch, var(--brand-500), white 80%);
--brand-300: color-mix(in oklch, var(--brand-500), white 40%);
--brand-700: color-mix(in oklch, var(--brand-500), black 25%);
--brand-900: color-mix(in oklch, var(--brand-500), black 50%);
/* Semantic color tokens */
--color-primary: var(--brand-500);
--color-primary-hover: var(--brand-700);
--color-primary-bg: var(--brand-100);
/* Utility colors */
--color-success: hsl(142, 71%, 45%);
--color-warning: hsl(38, 92%, 50%);
--color-error: hsl(0, 84%, 60%);
/* UI colors */
--color-text: hsl(220, 10%, 15%);
--color-muted: hsl(220, 8%, 55%);
--color-border: hsl(220, 12%, 88%);
--color-surface: hsl(220, 20%, 98%);
}
This system uses oklch for brand colors (perceptual uniformity), hsl for semantic colors (readability), and CSS custom properties throughout. You can manage and preview custom properties with our CSS Formatter.