问题
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