Published
CSS blend modes: beware the stacking context
I’m working on a site with a complex entanglement of blend modes, SVG backgrounds, gradient backgrounds, positioning, and transitions. I’ve run in to a bunch of issues with mix-blend-mode
not working as expected, and it almost always has to do with an inappropriate stacking context.
For posterity, this StackOverflow answer is a really good run-down of CSS combos that create new stacking contexts.
Now to see what I can do about browsers rendering color profiles slightly differently… 💀
Edit: UGHHHHHH it’s different in different browsers. Check out this CodePen in Chrome and Firefox vs Safari. This is why we can’t have nice things.
Edit 2: See the answer to the cross-browser problem from the previous CodePen, via Gregory Cadars (view thread). So Safari is actually behaving correctly, but it’s still a stacking context issue.
To recap: I’m trying to display a “fixed” gradient background with content that scrolls over the top of it. Within this content, only the images have mix-blend-mode: overlay
. In the original CodePen, I’m achieving this via a fixed position, 100% width + 100% height element with a linear gradient. This is within the same wrapper as the content.
My example is working in Chrome and Firefox. In Safari, it is effectively as if the blend mode hasn’t been applied. Though I’m not sure why the difference between browsers, it does make sense that a fixed position element would still create a new stacking context regardless of its parent.
In Gregory’s example, he’s removed the fixed position element with the gradient and instead applied the gradient background to the wrapper, as well as background-attachment: fixed
via the background
shorthand. This achieves the exact same effect, without stacking context issues.
The only thing that gives me pause is performance… I remember running in to some issues when I considered using background-attachment: fixed
for Elizabeth Peyton’s Eternal Return. I can’t remember what it was exactly but it had to do with repainting on every scroll event (so, a lot!). I think that this article may give some context, but I’ll have to dig in to it further.
Related: See this CSS gradients resampling tool by Rutherford Craze for smoother gradients, shared by Gregory in the thread.
Twitter is a crappy place a lot of the time, but I love it for things like this.