Opacify HEX Color In CSS
I prefer using hexadecimal color formats. That’s mostly out of habit, and that #000
looks more clean than red-green-blue color format rgb(0, 0, 0)
. Though the new syntax allows to have rgb(0 0 0)
. Better, but still not my taste.
However, the need to opacify them has been disrupting my everyday workflow: finding/opening a tool, converting HEX to RGB, and storing two values has never felt right:
:root {
--green: #1a8745;
--green-rgb: 26 135 69;
}
p {
color: var(--green);
background-color: var(--green-rgb / 5%);
}
Having both does not make much sense from idealistic point of view. But there is a solution if you are a die hard HEX fan as I am…
Solution
Quickly gaining a good traction in browser support CSS spec has recently been supplemented by a bunch of new color manipulation functions that one of which is color-mix
:
p {
color: color-mix(in srgb, #1a8745, transparent 50%);
}
The end result is the same as using rgb(26 135 69 / 50%)
.
The actual value may be substituted with a custom property:
p {
color: color-mix(in srgb, var(--green), transparent 50%);
}
Good news is this works equaly good with RGB:
p {
color: color-mix(in srgb, rgb(26 135 69), transparent 50%);
}
The syntax is quite verbose, but that could easily be addressed by a custom PostCSS function:
module.exports = {
plugins: {
"postcss-functions": {
function: {
"color-opacity": function (color, opacity) {
opacity = (1 - parseFloat(opacity)) * 100
return `color-mix(in srgb, ${color}, transparent ${opacity}%)`
},
},
},
},
}
Contrary to native implementation I’m using a number in the range 0.0
to 1.0
format for defining opacity:
p {
color: color-opacity(var(--green), 0.5);
background-color: color-opacity(#1a8745, 0.1);
border-color: color-opacity(rgb(26 135 69), 0.1);
}
Stylelint might have to say a few words about the new function, let’s silence it:
{
"rules": {
"function-no-unknown": [
true,
{
"ignoreFunctions": ["color-opacity"]
}
]
}
}
SASS
This is surely not the case on SASS based projects because it as a built-in function for that:
p {
color: rgba(#1a8745, 0.5);
}
But hey, we’re going back to the roots!