CSS animation reverts z-index?

39 Views Asked by At

I have a single div with a pseudo ::before element that has z-index: -1 in order to be put behind the actual div. The div is a 'ball' and the pseudo element is its shadow.

There is also a button and when clicked, an animation is put on the div so that it bounces up and down. The problem is that the shadow (pseudo div) - when the animation is enabled, and only then - is put in front of the ball (the actual div).

document.querySelector("button").addEventListener("click", () => {
  document.body.classList.toggle("disable-animation");
})
*,
*::before,
*::after {
  position: relative;
  min-width: 0;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
*::before,
*::after {
  content: '';
  position: absolute;
}

body {
  min-height: 100vh;
  background-color: rgba(0,0,0,.2);

  display: grid;
  place-items: center;
}

div[ball] {
  width: 10vw;
  aspect-ratio: 1;
  background-color: #fff;
  border-radius: 50%;
  --jump: 4vw;
  animation: var(--animation);
  animation-timing-function: ease-in-out;
}
div[ball]::before {
  width: 100%;
  height: 15%;
  bottom: -.5vw;
  background-color: rgba(0,0,0,.1);
  border-radius: 50%;
  z-index: -1;
  --jump: -4vw;
  animation: var(--animation);
  animation-timing-function: ease-in-out;
}
@keyframes ball-jump {
  50% {
    transform: translate3d(0, calc(-1 * var(--jump)), 0);
  }
}
.disable-animation {
  --animation: ball-jump 1s infinite;
}
<div ball></div>
<button>Toggle animation</button>

I've tried this example in Firefox 123, Google Chrome 122.0.6261.95 and Microsoft Edge 121.0.2277.128. Because Firefox and the others do not share rendering engine I assume that it is not a bug but me doing something wrong. Just don't know what?

1

There are 1 best solutions below

1
Temani Afif On BEST ANSWER

Use both pseudo-elements to create the animation. This will fix the z-index issue and avoid having to deal with another animation to revert the one applied on the main element

document.querySelector("button").addEventListener("click", () => {
  document.body.classList.toggle("disable-animation");
})
body {
  margin: 0;
  min-height: 100vh;
  background-color: rgba(0,0,0,.2);

  display: grid;
  place-items: center;
}

div[ball] {
  width: 10vw;
  aspect-ratio: 1;
  position: relative;
}
div[ball]::before {
  content:"";
  position: absolute;
  width: 100%;
  height: 15%;
  bottom: -.5vw;
  background-color: rgba(0,0,0,.1);
  border-radius: 50%;
}
div[ball]::after {
  content:"";
  position: absolute;
  inset: 0;
  background-color: #fff;
  border-radius: 50%;
  --jump: 4vw;
  animation: var(--animation);
  animation-timing-function: ease-in-out;
}
@keyframes ball-jump {
  50% {
    transform: translate3d(0, calc(-1 * var(--jump)), 0);
  }
}
.disable-animation {
  --animation: ball-jump 1s infinite;
}
<div ball></div>
<button>Toggle animation</button>