3

I have a setup that uses nested, absolute-positioned divs, and I need mix-blend-mode to blend the elements of a div with all of elements that have a lower z-index than that div.

The catch is that each div must have its own independent z-index (this cannot be changed for accessibility reasons).

This is easier to explain with an example:

#layer-1 {
  width: 700px;
  height: 700px;
  position: absolute;
  background-color: maroon;
  z-index: 1;
}

#layer-2 {
  position: absolute;
  height: 100px;
  width: 200px;
  z-index: 2;
}

#layer-3 {
  position: absolute;
  z-index: 3;
  mix-blend-mode: darken;
}

#layer-3 img {
  width: 300px;
}
<div id="layer-1"></div>

<div id="layer-2">

  <div id="layer-3">
    <img src="https://i.picsum.photos/id/100/2500/1656.jpg" />
  </div>

</div>

I need the image that's inside of layer-3 to blend with layer-1. If you remove the z-index from layer-2 in the fiddle, you will see that the blending works properly; however, this is not an option for accessibility reasons, as stated above.

I have made a jsfiddle here: https://jsfiddle.net/gabranches/v6cuL2o4/44/

Is there some way around this, or is this just a limitation of mix-blend-mode?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
gabranches
  • 71
  • 6
  • 1
    `display:contents;` to `#layer-2` – Rainbow Mar 26 '20 at 18:26
  • For simple background (color only) you could add `background: inherit` to the layers. This will break for background images because it will 'restart' the background again in the layer. – Simon_Weaver Jun 27 '22 at 19:52

1 Answers1

2

Simply apply the mix-blend-mode to the div #layer-2. This one is on the same stacking context with #layer-1. #layer-3 or img cannot blend directly with #layer-1

#layer-1 {
  width: 700px;
  height: 700px;
  position: absolute;
  background-color: maroon;
  z-index: 1;
}

#layer-2 {
  position: absolute;
  height: 100px;
  width: 200px;
  z-index: 2;
  mix-blend-mode: darken;
}

#layer-3 {
  position: absolute;
  z-index: 3;
}

#layer-3 img {
  width: 300px;
}
<div id="layer-1"></div>

<div id="layer-2">

  <div id="layer-3">
    <img src="https://i.picsum.photos/id/100/2500/1656.jpg" />
  </div>

</div>

From the specification:

Everything in CSS that creates a stacking context must be considered an ‘isolated’ group. HTML elements themselves should not create groups.

An element that has blending applied, must blend with all the underlying content of the stacking context that element belongs to.

Related question for more detail about stacking context: Why can't an element with a z-index value cover its child?

Community
  • 1
  • 1
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • I appreciate the response, but that would also add `mix-blend-mode` to other layers that might be inside of `#layer-2` that should not have the blend mode -sorry I should have included that in my example – gabranches Mar 26 '20 at 20:21
  • 1
    @gabranches in this case it won't be possible if you keep the use of z-index. If a stacking context is created then you cannot have only some elements on that stacking context to blend with outside element. Either all the stacking context can blend or not. – Temani Afif Mar 26 '20 at 20:28
  • @gabranches by the way I am pretty sure that we can overcome the z-index and don't use it if you share a complete code where you think it's necessary – Temani Afif Mar 26 '20 at 21:22