Meet the #RRGGBBAA CSS color syntax

Hash symbol

CSS color is about to get interesting. CSS Color Module Level 4 introduces new color spaces such as hwb() and lab(), and a color-mod() function that will let us change how we blend colors for the web.

But it also introduces some syntax changes to the mix, such as hexadecimal #rrggbbaa/#rgba notation. Since this change has shipped in some browsers, it's a good time to take a look.

RGB colors and hex values

But first, a quick refresher on RGB color. RGB — also abbreviated sRGB — is an additive color model. Red, green, and blue function as primary colors or channels that are mixed to form other colors. Mixing red and green for example, produces yellow, a secondary color.

Red + blue makes magenta. Red + green makes yellow. Green plus blue makes cyan

Each color channel in an RGB color is typically expressed as an integer between 0 and 255 — that's 00 through ff using a hexadecimal (base 16) system. The relative proportions of red, blue, and green determine what color our eyes perceive. Yellow, expressed using hexadecimal notation, is #ffff00. Both its red and green channels have the same maximum value (255 /ff).

#RRGGBBAA notation

#rrggbbaa notation works much the same way as #rrggbb notation, but with the addition of an alpha channel. Here too, accepted values range from 00ff. But rather than channel intensity, this value indicates transparency: 00 is fully transparent; ff is fully opaque.

Red, Green, and Blue at full opacity and about 50% opacity using RRGGBBAA notation

A fully opaque red, expressed using #rrggbbaa notation, is simply #ff0000ff. But let's say we wanted to use a red that was about 50% transparent. We could eyeball it, or use some math and JavaScript to calculate the hexadecimal value.

Converting from decimal to hex and back

As I mentioned earlier, color channel values range from 0 through 255, using a decimal system. We can convert any decimal number to a hexadecimal one using Number.prototype.toString().

Number.prototype.toString() accepts an optional radix or base argument between 2 (binary) and 32. To convert from decimal to hexadecimal, use 16.

console.log((16).toString(16)); // prints "10"

console.log((255).toString(16)); // prints "ff"

To find our 50% point, we need to multiply our maximum value of 255 by 0.5, and convert the result.

console.log((255 * 0.5).toString(16)); // prints "7f.8"

The value returned is 7f.8, which isn't valid for CSS. But dropping the .8 gets us pretty close. A 50% transparent red is roughly equivalent to #ff00ff7f.

Keep in mind that decimal numbers between 1 and 15 return a single character string. Left pad the value with a 0 before using it in CSS (e.g. 15 needs to be 0f instead of just f).

If you want to check your math, you can reverse the conversion — that is go from a hexadecimal to a decimal number — using parseInt. Using parseInt('7f', 16) returns 127. That's slightly less than 50% of 255.

Shortened #rgba syntax

The additional alpha channel value also applies to the shortened hexadecimal form. Just as we can use #f00 instead of #ff0000, we can use #f00f instead of #ff0000ff. All compute to opaque red (rgb(255, 0, 0)).

Browser support

To date, Firefox (49+) and Safari (10+) are the only browsers that support #rgba and #rrggbbaa notation out of the box. Support exists in Chrome, but Experimental Web Platform features must be enabled (see: chrome://flags) first.

It's safe to use this feature with a fallback, or stick to using the rgba() function.

Subscribe to the Webinista (Not) Weekly

A mix of tech, business, culture and a smidge of humble bragging. I send it sporadically, but no more than twice per month.

View old newsletters