3

I have tried this a lot of different ways, and cannot make it so that the .pink and .green divs blend with one another, but not the background color of the parent element, .wrapper.

.wrapper {
  background-color: blue;
  height: 100vh;
  width: 100%;
  isolation: isolate;
}

.pink {
  background: hotpink;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  left: 10%;
  mix-blend-mode: multiply;
}

.green {
  background: limegreen;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  right: 10%;
  mix-blend-mode: multiply;
}
<div class="wrapper">
  <div class="pink"></div>
  <div class="green"></div>
</div>

Or, see the fiddle: https://jsfiddle.net/grettynebraska/9dr6vspy/5/#&togetherjs=breFHFSfEd

My goal is simply to have a pink and green div that blend with eachother, and live atop a black background, with whom they do not blend.

I tried using absolute position, and sitting the pink/green divs and the wrapper next to one another, as siblings. However, all elements still blended.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Gretie
  • 31
  • 1
  • 2

1 Answers1

4

I would consdier an extra wrapper where you set a z-index in order to create a staking context thus the element will no more blend with the blue element:

.wrapper {
  background-color: blue;
  height: 100vh;
  width: 100%;
}
.wrapper > div {
  position:absolute;
  height: 100vh;
  left:0;
  right:0;
  z-index:0;
  top:0;
}

.pink {
  background: hotpink;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  left: 10%;
  mix-blend-mode: multiply;
}

.green {
  background: limegreen;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  right: 10%;
  mix-blend-mode: multiply;
}
<div class="wrapper">
  <div>
    <div class="pink"></div>
    <div class="green"></div>
  </div>
</div>

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 [CSS21] that that element belongs to. ref

So the main trick is to have the elements in a stacking context where the blue element doesn't belong. If the wrapper element is their direct parent element it won't be trivial to make them in different stacking context thus the need of an extra wrapper.


Isolation won't help you, because it will simply make the wrapper creating a stacking context, so it won't isolate the wrapper from its child but from all the elements outside. if you apply it to the extra wrapper it will work exactly like setting z-index or any other property that create a stacking context.

.wrapper {
  background-color: blue;
  height: 100vh;
  width: 100%;
}
.wrapper > div {
  position:absolute;
  height: 100vh;
  left:0;
  right:0;
  isolation:isolate;
  top:0;
}

.pink {
  background: hotpink;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  left: 10%;
  mix-blend-mode: multiply;
}

.green {
  background: limegreen;
  height: 80%;
  width: 50%;
  position: absolute;
  z-index: 1;
  top: 0;
  right: 10%;
  mix-blend-mode: multiply;
}
<div class="wrapper">
  <div>
    <div class="pink"></div>
    <div class="green"></div>
  </div>
</div>
Community
  • 1
  • 1
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 3
    A little addendum is that an extra wrapper with `isolation: isolate` will also create a stacking context as will using a CSS `clip-path`. – Bryce Howitson Feb 25 '19 at 22:33
  • @BryceHowitson yes, like the last example I made ;) and I also compared with all the property that create a stacking context (add link listing all of them, clip-path included) – Temani Afif Feb 25 '19 at 22:35
  • Hadn't looked at that list but figured I'd make it obvious for anyone like me who doesn't read... :) That list is good though, and it reminded me that `transforms` also create a stacking context which could negatively impact a blend depending on how its used. – Bryce Howitson Feb 25 '19 at 22:41
  • @BryceHowitson transform is the worst, it also create a containing block for fixed element ;) so it also break the fixed element – Temani Afif Feb 25 '19 at 22:44
  • thanks. So, when I create the extra div inside of the wrapper, and position it absolute, I create a stacking context for .wrapper > div, and the two rectangles it houses. This makes sense. What I do not understand is why the blending also occurs when I remove .wrapper > div from the .wrapper, and place it as a sibling adjacent to .wrapper, and set .wrapper > div still to be absolutely positioned, laying over the .wrapper background color. In this case, I still have the rectangles blending with .wrapper, though they are adjacent and .wrapper > div is absolute. – Gretie Feb 27 '19 at 14:19
  • @Gretie it's not the absolute that create a stacking context but the z-index. absolute only allow me to use z-index (you can use relative instead and it will also work). Also sibling or childs is the same because all the trick is the stacking context. if they are sibling and you also set z-index you will avoid the blending (https://jsfiddle.net/cysz612m/) ... basically whataver the structure is, the colored element need to belong inside a stacking context different from the wrapper one to not blend with it. – Temani Afif Feb 27 '19 at 14:25