Meet the #RRGGBBAA CSS color syntax
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.
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 00
–ff
. But rather than channel intensity, this value indicates transparency: 00
is fully transparent; ff
is fully opaque.
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.
Get CSS Master
Did you learn something from this blog post? You might like the latest edition of CSS Master. It contains several nuggets of CSS joy like this one. Buy now from SitePoint