rounded shadow CSS

2019-08-12 14:26发布

I found the following : https://www.prowebdesign.ro/round-brush-like-responsive-drop-shadows-with-css3-and-no-images/

which seems amazing : full css and dynamic radial shadows!

great. only I can't reproduce on consecutive items :

.body{
  background: white;
}

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

https://codepen.io/anon/pen/zLxNoE

what am I missing?

1条回答
贼婆χ
2楼-- · 2019-08-12 14:56

First the body element is having a white background and your elements a shadow in their pseudo elements. Let's consider the painting order and we will see that the white background is painted above your shadows:

The stacking context background and most negative positioned stacking contexts are at the bottom of the stack, while the most positive positioned stacking contexts are at the top of the stack.

And if we check later we will see this:

'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one.

Your pseudo element are positioned descendants of .item and this one is having a z-index:auto so they belong to the stacking context of the parent element which is .body and this one is not creating a stacking context so we move upper. In other words, we have only one stacking context in this case where all the element belong and since the pseudo element have a negative z-index they will be printed first considering the painting order.

To avoid this we need to play with stacking context. We can for example add z-index:0 to .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>

If we refer to the same specification we will see:

For those with 'z-index: 0' treat the stacking context generated atomically.

So the pseudo element will now belong to the stacking context created by .item and will be printed above the background of .body.

We can also apply some styling to the .body in order to create another stacking context:

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

In this case, we added a transformation to the .body so this one will create a new stacking context and the pseudo elements will belong to it; thus the shadow will also be printed above the white background.


You will also notice a clear difference between both cases. In the first one, the shadow of an element overlap the pervious element and the shadow is printed above the grey background BUT not in the second case. It's again the painting order!

For the first case, the pseudo elements belong to the stacking context of .item so the order will be : print the first .item with all its descendants then print the second one and so on. Then inside .item we first print the background then consider the descendants (the pseudo elements and their shadows).

For the second case, the pseudo elements belong to the stacking context of .body so inside it we first print the white background then all the negative z-index (the pseudo elements and their shadows) then we print all the .item.


If we get back to the intial code you will also notice that the first element is having its shadow painted correctly but considering the above explanation it should not be. It's because you are facing a margin-collapsing issue making the margin-top of the first element to go to .body thus the shadow of the first one is overflowing the .body BUT still painted above it.

If you add a small padding to .body the shadow will disappear because the margin-top will be kept on the top element and the white background will hide the shadow because it will cover the area of the 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>

Now only the bottom shadow is visible because we have no margin-bottom thus we have an overflow like we had initially with the first one when there was a margin-collapsing.

查看更多
登录 后发表回答