使用CSS混合模式隔离:如何防止元素与父元素混合

3

我已经尝试了很多种不同的方法,但无法使 .pink 和 .green div 元素混合在一起,而不是与父元素 .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>

或者,查看代码示例:https://jsfiddle.net/grettynebraska/9dr6vspy/5/#&togetherjs=breFHFSfEd

我的目标只是让一个粉色和绿色的div相互融合,并位于黑色背景之上,而它们不会与黑色背景融合在一起。

我尝试使用绝对定位,将粉色/绿色的div和包装器作为兄弟元素并排放置。然而,所有元素仍然混合在一起。

1个回答

4

我建议再加一层包装,给它设置一个 z-index,从而创建一个叠放上下文,这样元素就不会再与蓝色的元素混合了:

.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>

CSS中创建了层叠上下文的所有元素都必须被视为“隔离”的组。HTML元素本身不应该创建组。

应用了混合模式的元素必须与其所属的层叠上下文中的所有底层内容混合。[CSS21] ref

因此,主要的技巧是将元素放入一个层叠上下文中,使蓝色元素不属于其中。如果包装元素是它们的直接父元素,则将它们放入不同的层叠上下文中不会很容易,因此需要额外添加一个包装器。


隔离无法帮助你,因为它只会使包装器创建一个层叠上下文,因此它不会将包装器与其子元素隔离开来,而是与外部的所有元素隔离开来。如果将其应用于额外的包装器,则其效果与设置z-index任何其他创建层叠上下文的属性一样。

.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>


3
一个小补充是,使用“isolation: isolate”创建额外的包装器,以及使用CSS“clip-path”也将创建堆叠上下文。 - Bryce Howitson
@BryceHowitson 是的,就像我之前举的例子一样;我还比较了所有创建堆叠上下文的属性(包括剪辑路径),附上链接列出了它们。 - Temani Afif
没有看过那个列表,但我觉得我会让它变得明显,适合像我这样不阅读的人...:) 那个列表很好,它提醒了我 transforms 也会创建一个堆叠上下文,这可能会对混合产生负面影响,具体取决于它的使用方式。 - Bryce Howitson
@BryceHowitson transform 是最糟糕的,它还为固定元素创建了一个包含块;因此,它也会破坏固定元素。 - Temani Afif
谢谢。因此,当我在包装器内部创建额外的div并将其定位为absolute时,我为.wrapper > div和它所包含的两个矩形创建了一个堆叠上下文。这是有道理的。我不理解的是,为什么当我从.wrapper中删除.wrapper > div,并将其放置为相邻的同级元素,并将.wrapper > div仍设置为绝对定位,覆盖.wrapper的背景颜色时,混合仍然发生。在这种情况下,虽然它们相邻且.wrapper > div是绝对的,但仍然有矩形与.wrapper混合。 - Gretie
@Gretie,创建堆叠上下文的不是absolute,而是z-index。absolute只允许我使用z-index(你也可以使用relative,它也可以工作)。此外,兄弟或子元素是相同的,因为所有的技巧都在于堆叠上下文。如果它们是兄弟姐妹,并且您还设置了z-index,则可以避免混合(https://jsfiddle.net/cysz612m/)...基本上无论结构如何,彩色元素都需要属于与包装器不同的堆叠上下文,以避免与其混合。 - Temani Afif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接