CSS Color Formats
Every color in CSS, from a plain background to a gradient stop, has to be written in one of a handful of formats. They all describe the same underlying set of colors, so picking one is mostly about readability, browser support, and whether you need transparency, not about what's technically correct. This page walks through each format: what it looks like, how it works, and when it actually matters which one you reach for.
Hex
A hex code packs the red, green, and blue channels into a single 6-character string, each pair running from 00 to FF. It's the most compact format on this list, and the one most design tools (Figma, Photoshop, browser eyedroppers) copy to your clipboard by default, which is probably why it's the format most people reach for first.
color: #RRGGBB;
background-color: #FF6347;
For transparency, an 8-digit hex code (#RRGGBBAA) adds two more characters for the alpha channel. Support for 8-digit hex is a little newer than 6-digit, so if you need broad legacy browser coverage, rgba() is the safer choice for transparent colors.
RGB and RGBA
rgb() spells out the same red, green, and blue values as hex, but as plain numbers from 0 to 255 instead of a packed code. Nothing changes visually between the two: #FF6347 and rgb(255, 99, 71) are the identical color. The advantage of rgb() is that it's easier to read and hand-tune, since you can see and edit each channel directly rather than decoding hex pairs.
color: rgb(red, green, blue); color: rgba(red, green, blue, alpha);
background-color: rgba(255, 99, 71, 0.6);
Modern CSS also accepts a space-separated syntax with a slash for alpha, rgb(255 99 71 / 60%), which does the same thing as rgba() without needing a separate function name. Both are valid; rgba() still has the widest support across older browsers.
HSL and HSLA
hsl() describes a color by Hue (a position on the color wheel, 0 to 360 degrees), Saturation, and Lightness, instead of red, green, and blue channels. This is the format worth learning even if you default to hex most of the time, because common edits become trivial: "a bit lighter" or "more muted" is a single number change, rather than recomputing three RGB channels by feel.
color: hsl(hue, saturation%, lightness%); color: hsla(hue, saturation%, lightness%, alpha);
background-color: hsl(9, 100%, 64%);
A practical use case: to build a set of lighter or darker variants of one brand color, keep the hue and saturation fixed and step the lightness value up or down. That's exactly how this site's own color pages generate shade and tint swatches for every named color.
HWB
hwb() is a less common relative of HSL: instead of saturation and lightness, it mixes a Hue with how much White and how much Black to add. It's arguably more intuitive for manual tweaking (more white makes it more pastel, more black makes it darker), but it's rarely seen in real stylesheets since hsl() already covers the same ground for most people.
color: hwb(hue whiteness% blackness%);
OKLCH and Other Modern Formats
Hex, RGB, and HSL all share a limitation: they're built on the sRGB color space, which can't represent every color a modern screen can actually display, and their idea of "lightness" doesn't match how the human eye perceives brightness across different hues. Two equally-bright-looking colors can have very different lightness numbers in HSL, which is annoying when you're building a palette and expect consistent steps.
oklch() fixes this. It uses Lightness, Chroma (roughly, how saturated), and Hue, calculated in a perceptually uniform space, so a given lightness value looks equally bright regardless of hue. It can also reach colors outside sRGB entirely, on displays that support them. This is also why it's increasingly used for gradients: interpolating between two distant hues in OKLCH avoids the muddy, grayed-out middle that plain RGB interpolation often produces.
color: oklch(lightness% chroma hue);
background-color: oklch(70% 0.19 30);
lab() and lch() are close relatives built on a similar idea, also worth knowing about but less commonly used day to day than oklch().
Browser Support for OKLCH
| Chrome | Edge | Firefox | Safari | Opera | iOS Safari |
|---|---|---|---|---|---|
| 111+ | 111+ | 113+ | 15.4+ | 97+ | 15.4+ |
Widely supported in every current browser since mid-2023. If you need to support older browsers, provide a hex or rgb() fallback before the oklch() declaration; a browser that doesn't understand oklch() will just ignore that line and keep the earlier one. You can check the latest numbers on Can I Use.
Which Format Should I Use?
- Hex, for a quick default when you're pasting a color from a design tool.
- rgba() or hsla(), when you need transparency and want the widest browser support.
- hsl(), when you're hand-tuning lightness or saturation, or generating shade/tint variants.
- oklch(), when you're building a multi-color palette and want each step to look evenly spaced.
- A named color, only for quick prototypes; the 141 names cover far fewer colors than hex, rgb, or hsl can express.
Converting Between Formats
Need to go from one format to another? The Hex to RGB and RGB to Hex converters handle that instantly, and every page in the Color Names library lists a color's hex, RGB, and HSL values side by side.
FAQ
What are the different ways to specify a color in CSS?The most common are hex codes (
#FF6347), rgb()/rgba(), and hsl()/hsla(). CSS also supports 140+ predefined color names, plus newer functions like hwb(), lab(), lch(), and oklch() for a wider range of colors than the older formats can reach.
What's the difference between hex and rgb()?
Nothing visually. Hex and
rgb() describe the exact same set of colors, just written differently: hex packs red, green, and blue into a 6-character code, rgb() spells the same three values out as plain numbers from 0 to 255. rgb() is usually easier to read and hand-edit, hex is more compact and what most design tools copy by default.
Which CSS color format should I use?
Hex for a quick, compact default.
rgba() or hsla() when you need transparency. hsl() specifically when you want to tweak lightness or saturation by hand, since that's a single number instead of three recalculated channels. oklch() if you're building a palette with several related shades and want the lightness to actually look even across hues.
Can hex codes have transparency?
Yes, with 8-digit hex (
#RRGGBBAA). The last two characters set the alpha channel from 00 (fully transparent) to FF (fully opaque). Standard 6-digit hex has no transparency; use rgba() or hsla() if you need wider, older browser support for transparent colors.