-1

Why does my ::before pseudo-element not sit behind it's parent? I am creating a new stacking context and adding a z-index of -1.

codepen

  .panda {
    position: relative;
    border: 1.5vmin solid black;
    width: 45vmin;
    height: 45vmin;
    border-radius: 50%;
    background: #fff;
    z-index: 2;

    &:before {
      content: '';
      position: absolute;
      z-index: -1;
      width: 15vmin;
      height: 15vmin;
      background: black;
      border-radius: 50%;
      top: -4vmin;
      left: -2.1vmin;
      box-shadow: 30vmin 0 #000;
    }
  }
noclist
  • 1,659
  • 2
  • 25
  • 66
  • Your panda's eye and nose are nice – Rana Oct 08 '21 at 17:29
  • Thanks, wish I could get the ears behind his head. – noclist Oct 08 '21 at 17:33
  • Could you tell about this line `border-radius: 50% 50% 48% 52% / 21% 21% 79% 79%;` . And which part does create the ears – Rana Oct 08 '21 at 17:33
  • The part that creates the ears is the .panda:before – noclist Oct 08 '21 at 17:48
  • Yup found that and solution is to use `::after` in CSS(you know about CSS) but can you tell about the `border-radius: 50% 50% 48% 52% / 21% 21% 79% 79%;` – Rana Oct 08 '21 at 17:51
  • That border-radius is creating the oval shape of the eyes. – noclist Oct 08 '21 at 17:52
  • Yes that's right but as `border-radius` property is like this : `border-radius: top right bottom left` what are the value work with `/` after `/` – Rana Oct 08 '21 at 17:54
  • You can finer tune the individual corners of the border with those extra values. https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius – noclist Oct 08 '21 at 17:55

3 Answers3

2

::after inserts its content immediately before the end of the tag it's applied to but still inside the tag, z-index couldn't be lower than the z-index of the tag, so your approach won't work. But you could do ::after to the parent tag, which in your case has class 'circle'. As the inserted content will be relative to the wrapping tag, you should adjust the position of the contend related to this tag.

See a codepen example:

Codepen Example

See a snippet example here:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.canvas {
    background: #573d0e;
    height: 100vh;
    width: 100vw;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
  }

  .circle {
    width: 70vmin;
    height: 70vmin;
    background: #ffffff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    position: relative;
  }

  .circle:after {
      content: '';
      position: absolute;
      z-index: 1;
      width: 15vmin;
      height: 15vmin;
      background: black;
      border-radius: 50%;
      top: 10vmin;
      left: 12vmin;
      box-shadow: 30vmin 0 #000;
    }

.panda {
    position: relative;
    border: 1.5vmin solid black;
    width: 45vmin;
    height: 45vmin;
    border-radius: 50%;
    background: #fff;
    z-index: 2;

  }

  .eyes {
      position: relative;

    > * {
        position: absolute;
        width: 11vmin;
        height: 15vmin;
        background: #000;
        border-radius: 70px / 100px;
        left: 8.7vmin;
        top: 9vmin;
        transform: rotate(12deg);

        &:before,
        &:after {
          content: '';
          position: absolute;
        }

        &:before {
            width: 4vmin;
            height: 6vmin;
            background: white;
            border-radius: 76px / 100px;
            left: 5vmin;
            top: 3.2vmin;
            transform: rotate(348deg);
        }

        &:after {
          width: 2vmin;
          height: 3vmin;
          background: black;
          border-radius: 76px / 100px;
          left: 6.3vmin;
          top: 5vmin;
          transform: rotate(348deg);
        }
    }

    :last-child {
        transform: scale(-1, 1) rotate(12deg);
        left: 22.3vmin;
    }
  }

  .snout {
        position: absolute;
        width: 25vmin;
        height: 18vmin;
        top: 23vmin;
        left: 8.5vmin;
        bottom: 5vmin;
        background: #fff;
        border-radius: 50%;
        border: 1.5vmin solid black;

        &:before {
            content: '';
            position: absolute;
            width: 1.5vmin;
            height: 5vmin;
            left: 10vmin;
            top: 7vmin;
            background: black;
        }
  }

  .nose {
    position: absolute;
    width: 10vmin;
    height: 7vmin;
    left: 5.7vmin;
    top: 0.5vmin;
    background: black;
    border-radius: 50% 50% 48% 52% / 21% 21% 79% 79%;
  }

  .mouth {
        position: absolute;
        width: 9.6vmin;
        height: 5vmin;
        border-radius: 50%;
        border-bottom: 1.5vmin solid black;
        bottom: 1.6vmin;
        left: 6vmin;
  }
    <div class="canvas">
        <div class="circle">
            <div class="panda">
                <div class="eyes">
                    <div></div>
                    <div></div>
                </div>
                <div class="snout">
                    <div class="nose"></div>
                    <div class="mouth"></div>
                </div>
            </div>
        </div>
    </div>
Reflective
  • 3,854
  • 1
  • 13
  • 25
  • Thanks. So there's really no way to create a new stacking context from an elements direct parent? – noclist Oct 08 '21 at 19:17
  • I don't think there's a way in case of absolute positioning ... not 100% sure, it might work in some browsers but it won't be a stable solution – Reflective Oct 08 '21 at 19:26
0

.panda {
    position: relative;
    border: 1.5vmin solid black;
    width: 45vmin;
    height: 45vmin;
    border-radius: 50%;
    background: #fff;
    
    
  }
  .panda:after {
      content: '';
      position: absolute;
      z-index: -1;
      width: 15vmin;
      height: 15vmin;
      background: black;
      border-radius: 50%;
      top: -4vmin;
      left: -2.1vmin;
      box-shadow: 30vmin 0 #000;
    }
<div class="panda"></div>
Arezou Saremian
  • 508
  • 3
  • 8
0

Element always use the z-index of the parent. If a parent div has a z-index, all childs can't be set on a lower z-index. The minimum z-index always will be the parent one.

For you panda, the best solution is create a special div for ears out of ".panda" :

CSS :

.ears{
    position: absolute;
  z-index: 1;
  width: 15vmin;
  height: 15vmin;
  background: black;
  border-radius: 50%;
  top: 8vmin;
  left: 12vmin;
  box-shadow: 30vmin 0 #000;
}

HTML :

   <div class="canvas">
        <div class="circle">
          <div class="ears"></div>
            <div class="panda">
                <div class="eyes">
                    <div></div>
                    <div></div>
                </div>
                <div class="snout">
                    <div class="nose"></div>
                    <div class="mouth"></div>
                </div>
            </div>
        </div>
    </div>

You can fix ears on .circle. Live example : https://codepen.io/camillewemajin/pen/ExvYOBV

Camille
  • 847
  • 1
  • 7
  • 19
  • Thanks but you are supposed to be able to create a new stacking context of the `:before` by setting your pseudoelement to position: absolute; – noclist Oct 08 '21 at 17:51
  • You're right, set .circle on position relative ! Live example : https://codepen.io/camillewemajin/pen/ExvYOBV – Camille Oct 08 '21 at 17:53