csssass

Get css transition to not flash first


I am trying to make a css animation where the three parts of a word fade in from different directions but they are flashing first and then the animation is taking place.

I have added the code below to show the current iteration.

How do I fix this so you do not see the text until they fade in from each direction?

setTimeout(() => {
  let hOne = document.getElementsByTagName('h1');
  hOne[0].classList.add('active');
}, 1000);
.hero {
  width: 100%;
  height: auto;
  background-color: black;
  background-size: cover;
  background-position: center;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  overflow: hidden;
}
.hero h1 {
  font-family: "Montserrat", sans-serif;
  color: white;
  display: flex;
  opacity: 0;
  animation: fadeIn 1.5s ease-in-out forwards;
  font-size: 6rem;
}
.hero h1 span.one {
  display: block;
}
.hero h1 span.two {
  display: block;
}
.hero h1 span.three {
  display: block;
}
.hero h1.active span.one {
  animation: bounceOne 1.5s ease;
}
.hero h1.active span.two {
  animation: bounceTwo 1.5s ease;
}
.hero h1.active span.three {
  animation: bounceThree 1.5s ease;
}
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes bounceOne {
  0% {
    opacity: 0;
    transform: translateX(-100%);
  }
  30% {
    transform: translateX(10%);
  }
  50% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(0);
  }
}
@keyframes bounceTwo {
  0% {
    opacity: 0;
    transform: translateY(100%);
  }
  30% {
    transform: translateY(10%);
  }
  50% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(0);
  }
}
@keyframes bounceThree {
  0% {
    opacity: 0;
    transform: translateX(100%);
  }
  30% {
    transform: translateX(-10%);
  }
  50% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(0);
  }
}
<div class="hero">
  <h1 class="">
    <span class="one">One</span>
    <span class="two">Two</span>
    <span class="three">Three</span>
  </h1>
</div>


Solution

  • You are setting the animation for the fadeIn right off the bat here

    .hero h1 {
      ...
      animation: fadeIn 1.5s ease-in-out forwards;
      ...
    }
    

    On page load, this animation is activated because the element is loaded, and the h1 element itself has no class names attached to it, so it loads the animation in .hero h1. If you wanted to wait for the active class to be applied, you would also need to add the active class in a separate css selector.

    .hero h1.active {
       animation: fadeIn 1s ease-in-out forwards;
    }
    

    codepen