This week I was working on transferring the designs for the project I am on from Figma to a Drupal theme, when I came across a CSS property I’d never encountered before:
WTF is mix-blend-mode?
Even though I’ve been doing front-end work for over 20 years, in my defense there are at least 520 different CSS properties, so coming across a new one shouldn’t be that surprising really.
mix-blend-mode is actually a pretty cool property:
… sets how an element’s content should blend with the content of the element’s parent and the element’s background.
So it’s basically a way to make the text or other elements blend in with the background image/color that you are applying to it’s parent element. It can do a lot of really neat things like lighten, darken, multiply, hard and soft light and a bunch more (really, checkout the MDN link for some cool examples).
Which is all fun and good, except what if you need to blend the background but don’t want the text to blend in?
Here’s what I was dealing with:
The styling scenario is that the client wanted the textured background all across the footer, but for the “utility links” and the copyright, they should also have the background but with a darker overlay on top of it. The designer didn’t provide a separate file for that part of the background in Figma (grr…) but used
In case you can’t make it out (and I don’t blame you), the arrow in the screenshot is pointing to the utility links that, thanks to
mix-blend-mode, are impossible to read.
So if you have to use
mix-blend-mode but you need the text to appear as normal, what do you do?
Enter another (new to me) CSS propery:
Isolate all the things!
In essence, I think about
isolation similar to the stacking principal of
z-index in that you are isolating an element from it’s parent, a la putting an element atop of another one with
That’s basically exactly how MDN describes it as well:
The isolation CSS property determines whether an element must create a new stacking context.
It works different from the normal box model of CSS though, and is a bit more like CSS @container in my mind, in that you are taking something within another element and pulling it out and away from the styling of it’s parent. It’s less about positioning like
z-index would be, and more about controlling what gets applied to a more general container with a background image/color. Again, that’s how I think about it, you may see it differently :)
isolation property has a default of
auto and can also use standard items like
revert-layer (for CSS @layers) and
unset . But the one that you’re gonna want to use in many cases is simply
One of the keys to using it though, is that you need to set it to
position: relative in order for it to take effect. Doing that should isolate your text from the background color/image of the parent and make it stand out.
In my specific use case though, with only part of the parent element having the
mix-blend-mode: color-burn) applied, since the rest of the footer needed to have the standard background image without any color change, I had to get a little bit trickier.
I wrapped the two divs,
.copyright into a separate div wrapper called
.bottom-footer-wrapper. I gave it a
position: relative property and then, using the :before pseudo class on
.bottom-footer-wrapper, applied the
mix-blend-mode to that part specifically.
Within the pseudo class, I set it to be absolutely positioned and a width/height of 100%, and to ensure it appeared, set
content: ""; . After that, it’s just applying the
mix-blend-mode and we are all set.
Here is a quick Codepen example that I whipped up, since Micro.blog ain’t the best at displaying chunks of code:
And here is my finished example, with white links and proper styling!
Hopefully this post will help others who may have had the same problem I did in the past, but also show that there are still so many undiscovered CSS properties out there that we can use!