Use color-mix() to add transparency

I lean into CSS custom properties a lot in my day-to-day work. I use them to define almost every aspect of a website’s theme, including the colour palette—typically using hex codes.

Why hex? Whilst I’ve experimented a little with the newer colour formats, I still tend to use hex codes in production for their predictability and widespread support.

A typical example being:

:root {
  --color-dark: #212529;
  --color-mid: #6c757d;
  --color-light: #f8f9fa;
}

Though it’s not something I frequently need, there have been occasions where it would have been really handy to generate transparent variants of these custom properties.

It’s not valid to use a hex code like this:

:root {
  --color-dark: #212529;
}

.my-element {
  background-color: rgba(var(--color-dark), 0.75);
}

My previous workaround would usually involve using a pseudo-element to apply a semi-transparent overlay:

:root {
  --color-dark: #212529;
}

.my-element {
  position: relative;
}

.my-element::before {
  content: '';
  background-color: var(--color-dark);
  opacity: 0.75;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;  
}

Or creating an RGB custom property alongside its hex code counterpart:

:root {
  --color-dark: #212529;
  --color-dark-rgb: rgb(33 37 41);
}

However, thanks to color-mix(), it’s now possible to work around this more efficiently—especially as using a pseudo-element always felt like a bit of a hack. And adding extra custom properties doesn’t feel sustainable in the long term.

This CSS function has baseline support, so within the remit of the projects I work on, it’s more than sufficient. That said, it may not be suitable for every project—especially if older browsers or devices are a concern.

But now I can use my hex colour custom properties to write this in a much more succinct way:

:root {
  --color-dark: #212529;
}

.my-element {
  background-color: color-mix(in srgb, var(--color-dark) 75%, transparent);
}

Whilst this isn’t a deep dive into everything color-mix() can do, it’s one simple use case I’ve started incorporating into my workflow.

Further reading


back