React CSS animation-delay property does not work

Issue

just a quick question regarding animated elements in React.js – I have noticed that when trying to make use of the animation-delay property in CSS, that React does not seem to apply this rule at all for some reason.

For example, I am trying to make a basic loading component, which just has a series of basic circles moving about in sequence, the CSS for which is below:

.--loaderContainer {
    position: relative;
    left: 50%;
    top: 50%;
    transform: translateX(-50%), translateY(-50%);
    width: 4rem;
    height: 4rem;
}

.--loaderContainer:nth-child(n) {
    width: 1rem;
    height: 1rem;
    border-radius: 9999px;
    margin: 0;
    padding: 0;
    position: absolute;
    animation-name: spin;
    animation-duration: 2s;
    animation-timing-function: ease;
    animation-iteration-count: infinite;
    animation-fill-mode: both;
}

.--loaderContainer:first-child {
    background-color: red;
    transform: rotate(270deg);
    animation-delay: -1.5s;
}

.--loaderContainer:nth-child(2) {
    background-color: blue;
    transform: rotate(180deg);
    animation-delay: -1s;
}

.--loaderContainer:nth-child(3) {
    background-color: green;
    transform: rotate(90deg);
    animation-delay: -0.5s;
}

.--loaderContainer:nth-child(4) {
    background-color: yellow;
}

@keyframes spin {
    0%,
    100% {
        transform: translate(0);
    }
    25% {
        transform: translate(160%);
    }
    50% {
        transform: translate(160%, 160%);
    }
    75% {
        transform: translate(0, 160%);
    }
}

As far as I can tell, this should stagger each of the child elements in sequence, performing the same animation but at different times. However, for some reason, React simply plays the animation, with no delay whatsoever and has all four elements animate at the exact same time.

It seems like a really basic issue to be having and while I have looked up a variety of answers, I just can’t seem to find any concrete solutions, so would be super appreciative for any help. Thanks!

Solution

If all four circles are seen, I think this animation should be working properly.

The negative animation-delay values ensures that four circles start at different points of the animation, rather than putting an actual delay.

More about animation-delay

Without it, they will start at same point and move together while stacking with each other, resulting in only one circle is seen (the last yellow circle since it’s on top of stack).

Here is a basic example for testing the effect of animation-delay by toggling it on and off for all the circles, it can run with the "run code snippet" button below.

Hope it will help.

const btn = document.querySelector("button");
const loaders = document.querySelectorAll(".--loaderContainer");

btn.addEventListener("click", () => {
  loaders.forEach((loader) => loader.classList.toggle("no-delay"));
  btn.textContent = loaders[0].classList.contains("no-delay")
    ? "turn delay on"
    : "turn delay off";
});
.--loaderContainer {
  position: relative;
  left: 50%;
  top: 50%;
  transform: translateX(-50%), translateY(-50%);
  width: 4rem;
  height: 4rem;
}

.--loaderContainer:nth-child(n) {
  width: 1rem;
  height: 1rem;
  border-radius: 9999px;
  margin: 0;
  padding: 0;
  position: absolute;
  animation-name: spin;
  animation-duration: 2s;
  animation-timing-function: ease;
  animation-iteration-count: infinite;
  animation-fill-mode: both;
}

.--loaderContainer:first-child {
  background-color: red;
  transform: rotate(270deg);
  animation-delay: -1.5s;
}

.--loaderContainer:nth-child(2) {
  background-color: blue;
  transform: rotate(180deg);
  animation-delay: -1s;
}

.--loaderContainer:nth-child(3) {
  background-color: green;
  transform: rotate(90deg);
  animation-delay: -0.5s;
}

.--loaderContainer:nth-child(4) {
  background-color: yellow;
}

@keyframes spin {
  0%,
  100% {
    transform: translate(0);
  }
  25% {
    transform: translate(160%);
  }
  50% {
    transform: translate(160%, 160%);
  }
  75% {
    transform: translate(0, 160%);
  }
}

button {
  text-transform: uppercase;
  padding: 6px;
}

section {
  width: 100px;
  height: 100px;
  position: relative;
}

div.--loaderContainer.no-delay:nth-child(n) {
  animation-delay: 0s;
  opacity: 0.8;
}

body {
  background-color: #aaa;
}
<button>turn delay off</button>
<section>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
<div class="--loaderContainer"></div>
</section>

Answered By – John Li

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published