首先,body 元素具有白色背景,而您的元素在其伪元素中具有阴影。让我们考虑painting order,我们会看到白色背景画在你的阴影上方:
堆叠上下文背景和大多数负定位堆叠
上下文位于堆栈的底部,而最积极的
定位的堆栈上下文位于堆栈的顶部。
如果我们稍后检查,我们会看到:
'z-index: auto',将元素视为创建了新的堆叠
上下文,但任何定位的后代和后代实际上
创建一个新的堆叠上下文应该被认为是父级的一部分
堆叠上下文,而不是这个新的。
您的伪元素是.item 的定位后代,而这个具有z-index:auto,因此它们属于.body 父元素的堆叠上下文,而这个未创建 一个堆叠上下文,所以我们向上移动。换句话说,在这种情况下,我们只有一个堆叠上下文,其中所有元素都属于,并且由于伪元素有一个负数 z-index,因此考虑到绘制顺序,它们将首先被打印。
为避免这种情况,我们需要使用堆叠上下文。例如,我们可以将z-index:0 添加到.item
.body{
background: white;
}
.bother{
width: 500px;
background: lightgre;
margin-left:50px;
}
.item{
margin-top: 20px;
margin-left:50px;
background: grey;
width: 500px;
position: relative;
z-index:0;
}
.item:after{
content: "";
position: absolute;
z-index: -1;
box-shadow: 0 0 40px red;
bottom: 0;
width: 100%;
height: 50%;
left: 0;
border-radius: 100%;
}
<div class="body">
<div class="item">shadow me</div>
<div class="item">I should be shadowed but I'm also bothering</div>
<div class="bother">I'm bothering</div>
<div class="item">shadow me</div>
</div>
如果我们参考相同的规范,我们会看到:
对于那些具有 'z-index: 0' 的人,请处理生成的堆叠上下文
原子地。
所以伪元素现在将属于.item创建的堆叠上下文,并将打印在.body的背景之上。
我们还可以对.body 应用一些样式以创建另一个堆叠上下文:
.body{
background: white;
transform:translate(0)
}
.bother{
width: 500px;
background: lightgre;
margin-left:50px;
}
.item{
margin-top: 20px;
margin-left:50px;
background: grey;
width: 500px;
position: relative;
}
.item:after{
content: "";
position: absolute;
z-index: -1;
box-shadow: 0 0 40px red;
bottom: 0;
width: 100%;
height: 50%;
left: 0;
border-radius: 100%;
}
<div class="body">
<div class="item">shadow me</div>
<div class="item">I should be shadowed but I'm also bothering</div>
<div class="bother">I'm bothering</div>
<div class="item">shadow me</div>
</div>
在这种情况下,我们向.body 添加了一个转换,因此这个转换将创建一个新的堆叠上下文并且伪元素将属于它;因此阴影也将打印在白色背景之上。
您还会注意到两种情况之间的明显区别。在第一种情况下,元素的阴影与可渗透的元素重叠,并且阴影打印在灰色背景之上,但在第二种情况下则不然。又是绘画顺序!
对于第一种情况,伪元素属于.item 的堆叠上下文,因此顺序为:打印第一个.item 及其所有后代,然后打印第二个,依此类推。然后在.item 内部,我们首先打印背景,然后考虑后代(伪元素及其阴影)。
对于第二种情况,伪元素属于.body的堆叠上下文,所以在其中我们首先打印白色背景,然后打印所有负的z-index(伪元素及其阴影)然后我们打印所有@ 987654342@.
如果我们回到最初的代码,您还会注意到第一个元素的阴影绘制正确,但考虑到上面的解释,它不应该是这样。这是因为您面临边缘折叠问题,使第一个元素的margin-top 转到.body,因此第一个元素的阴影溢出了.body,但仍绘制在其上方。
如果您向.body 添加一个小填充,阴影将消失,因为margin-top 将保留在顶部元素上,而白色背景将隐藏阴影,因为它会覆盖margin-top 的区域
.body{
background: white;
padding:1px;
}
.bother{
width: 500px;
background: lightgre;
margin-left:50px;
}
.item{
margin-top: 20px;
margin-left:50px;
background: grey;
width: 500px;
position: relative;
}
.item:after{
content: "";
position: absolute;
z-index: -1;
box-shadow: 0 0 40px red;
bottom: 0;
width: 100%;
height: 50%;
left: 0;
border-radius: 100%;
}
<div class="body">
<div class="item">shadow me</div>
<div class="item">I should be shadowed but I'm also bothering</div>
<div class="bother">I'm bothering</div>
<div class="item">shadow me</div>
</div>
现在只有底部阴影是可见的,因为我们没有margin-bottom,因此我们有一个溢出,就像我们最初在边缘折叠时的第一个阴影一样。