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: mix-blend-mode
.
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 mix-blend-mode
instead.
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: isolation
.
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 z-index
.
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 :)
The isolation
property has a default of auto
and can also use standard items like inherit
, initial
, revert
, revert-layer
(for CSS @layers) and unset
. But the one that you’re gonna want to use in many cases is simply isolation: isolate;
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
(specifically 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, .utility-links
and .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:
See the Pen Isolating elements within mix-blend-mode by Adam Varn (@hotsauce) on CodePen.
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!