Mix-blend-mode working when applied to one element but not another

♀尐吖头ヾ 提交于 2021-02-11 08:44:22

问题


I am using mix-blend-mode on css-generated content to create a multiplied background effect.

When I apply this generated element to an outer wrapper it has the intended effect:

.standard-cover {
  background: blue;
  color: #fff;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 100%;
  display: flex;
}
.standard-cover:after {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
  content: "";
  background: blue;
  mix-blend-mode: multiply;
}
.image-wrap {
  line-height: 0;
}
img {
  object-fit: cover;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
}
.content-wrap {
  position: relative;
  text-align:center;
  z-index: 30;
  min-height: 1em;
  margin: auto;
  padding: 3.33%;
}
<div class="standard-cover">
  <div class="image-wrap">
    <img src="http://placeimg.com/480/480/nature" alt="Nature">
  </div>
  <div class="content-wrap">
    <div class="content">
      <h2>A title</h2>
      <p>A pagragraph</p>
    </div>
  </div>
</div>

When I apply it to an inner wrapper it does not:

.standard-cover {
  position: absolute;
  background: blue;
  color: #fff;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 100%;
  display: flex;
}
.image-wrap {
  line-height: 0;
}
img {
  object-fit: cover;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
}
.content-wrap {
  position: relative;
  text-align:center;
  z-index: 30;
  min-height: 1em;
  margin: auto;
  padding: 3.33%;
}
.content-wrap:after {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
  content: "";
  background: blue;
  mix-blend-mode: multiply;
}
.content {
  position: relative;
  z-index: 30;
}
<div class="standard-cover">
  <div class="image-wrap">
    <img src="http://placeimg.com/480/480/nature" alt="Nature">
  </div>
  <div class="content-wrap">
    <div class="content">
      <h2>A title</h2>
      <p>A pagragraph</p>
    </div>
  </div>
</div>

In both cases the actual css that applies the faux background color is identical:

.class:after {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
  content: "";
  background: blue;
  mix-blend-mode: multiply;
}

But in the first example it in fact applies the mix-blend-mode effect properly. In the second example it does not (despite inspectors confirming that the mix-blend-mode attribute is present and set to multiply).

Is there some nuance to the mix-blend-mode spec that I'm not understanding? Or am I missing some crucial something in my code?


回答1:


It's all about stacking context. In the first case, the pseudo element is applied to .standard-cover where there is the background so its a child element of it and mix-blend-mode will work correctly because both belong to the same stacking context. In the second case, you moved the pseudo element to .content-wrap and there is a z-index specified so now it belong to another stacking context and mix-blend-mode will no more have effect outside.

An easy solution is to remove the z-index from .content-wrap to avoid creating a stacking context and mix-blend-mode will work like intended:

.standard-cover {
  position: absolute;
  background: blue;
  color: #fff;
  top: 0;
  left: 0;
  width: 100%;
  min-height: 100%;
  display: flex;
}
.image-wrap {
  line-height: 0;
}
img {
  object-fit: cover;
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
}
.content-wrap {
  position: relative;
  text-align:center;
  min-height: 1em;
  margin: auto;
  padding: 3.33%;
}
.content-wrap:after {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 20;
  content: "";
  background: blue;
  mix-blend-mode: multiply;
}
.content {
  position: relative;
  z-index: 30;
}
<div class="standard-cover">
  <div class="image-wrap">
    <img src="http://placeimg.com/480/480/nature" alt="Nature">
  </div>
  <div class="content-wrap">
    <div class="content">
      <h2>A title</h2>
      <p>A pagragraph</p>
    </div>
  </div>
</div>

Note: Applying a blendmode other than normal to the element must establish a new stacking context [CSS21]. This group must then be blended and composited with the stacking context that contains the element. ref



来源:https://stackoverflow.com/questions/59419494/mix-blend-mode-working-when-applied-to-one-element-but-not-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!