mix-blend-mode is broken by 3D transformations on page
I was having a similar issue, except that applying a mix-blend-mode
(multiply) higher on the page broke my transform
s lower on the page (using Chrome on Mac). I was able to fix this by applying a z-index
rule to the mix-blend-mode
div (don't forget to set a position
, too).
I'm not entirely sure if this is a bug or if it is expected behavior due to the properties of stacking contexts, though.
You can try to also apply a null transform (3D layer promotion) to the element that has mix-blend-mode
specified:
.content { mix-blend-mode: difference; transform: translate3d(0, 0, 0);}
This way, Chrome can successfully blend the two 3D layers together, instead of failing to blend a 3D layer and a 2D layer.
Here's a snippet demonstrating the problem and the solution:
function change(event) { var content = document.querySelector(".content") content.className = event.target.checked ? "content content-with-transform" : "content"}
.parent { text-align: center; padding: 2rem; font-size: 5rem; font-weight: 700;}.fixed { position: fixed; top: 0; left: 0; right: 0; height: 4rem; background-color: #AB1795; transform: translate3d(0, 0, 0); z-index: -1;}.content { mix-blend-mode: difference; background-color: #167CFB;}.content-with-transform { transform: translate3d(0, 0, 0);}
<div class="parent"> <div class="fixed"></div> <div class="content">Content</div></div><label><input type="checkbox" onchange="change(event)"/> Also transform other element</label>
(I stumbled onto this problem when using will-change: transform
, not an actual transform, but the solution is the same.)
I realise this is a pretty old thread, but I was having the same issue with janky transforms in Webkit/Blink using the Masonry Isotope plugin with a mix-blend-mode overlay on the grid sections until I added the following CSS to the element that was being transformed. i.e. the masonry grid element
I'm answering this in case it helps someone in future.
[your-selector-goes-here] { perspective:1000px; -webkit-backface-visibility: visible; backface-visibility: visible;}