DANIEL DANIEL - 6 months ago 34
CSS Question

How to animate CSS with a delay between an unknown number of elements

I'm a beginner in CSS Animations.

I have many itens in a row (using bootstrap - then the number of elements is different for each resolution)

<div class="row IconAnimate">

<div class="col-xs-12 col-sm-4 col-lg-2">
<div><i class="fa fa-trademark fa-3x"></i>
<h4><strong>TITLE 1</h4>
<p>BLA BLA BLA</p>
</div>
</div>

<div class="col-xs-12 col-sm-4 col-lg-2">
<div><i class="fa fa-paint-brush fa-3x"></i>
<h4><strong>TITLE 2</strong></h4>
<p>BLA BLA BLA</p>
</div>
</div>

</div>


With this I have rows with 6, 3 and 1 element. (col-xs-12, sm-4 and lg-2) - ok?

each row have a SCROLL down animation (created by the "animation-element side-left")

In other words, if I scroll down the browser, the row will be animated.

Until now - NO PROBLEM.

Now I want to ANIMATE THE ICON (in this case the "FA-TRADEMARK" icon)

with a FadeIn animation.

But..

MY PROBLEM:

How I can animated EACH ICON with a delay of 3s between each icon?

I got this:

@keyframes FadeIn {
0% { opacity:0; transform:scale(.1);}
85% {opacity:1; transform:scale(1.05);}
100% {transform:scale(1); }
}

.IconAnimate i { animation: FadeIn 1s linear; animation-fill-mode:both; }
.IconAnimate i:nth-child(1){ animation-delay: 3s }
.IconAnimate i:nth-child(2){ animation-delay: 6s }
.IconAnimate i:nth-child(3){ animation-delay: 9s }
.IconAnimate i:nth-child(4){ animation-delay: 12s }


But with this code I got the animation, but, I need to know How many itens I have in the row.

Is there a way to make the animation if I dont know how may elements I will have in each row?

THE JSFIDDLE: https://jsfiddle.net/mydjnfLn/

Answer

Solution 1: jQuery without CSS

You can use jQuery's animate and delay functions to achieve this, it's quite simple, here's the code:

$('.IconAnimate i').each(function(i) {
  $(this).css('opacity', 0);
  $(this).delay(1000 * i).animate({
    'opacity': 1.0
  }, 450);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<div class="row IconAnimate">

  <div class="col-xs-12 col-sm-4 col-lg-2">
    <div><i class="fa fa-trademark fa-3x"></i>
      <h4><strong>TITLE 1</h4>
      <p>BLA BLA BLA</p>
    </div>
  </div>

  <div class="col-xs-12 col-sm-4 col-lg-2">
    <div><i class="fa fa-paint-brush fa-3x"></i> 
      <h4><strong>TITLE 2</strong></h4>
      <p>BLA BLA BLA</p>
    </div>
  </div>

</div>

Of course this is just an example, I leave it to you to figure out what properties you have to animate and how to get the desired effect.

Solution 2: jQuery/pure javascript and CSS animations

A, in my opinion, more versatile solution would be to use a CSS class to enable the animation and dynamically add this class to your i elements via javascript. While you can use jQuery for this if you'd like, you don't have to, the code is simple enough to do it using pure javascript:

function animateNext() {
  var elements = document.querySelectorAll('.IconAnimate i:not(.show)');
  if (elements.length) {
    elements[0].classList.add('show');
    setTimeout(animateNext,1000);
  }
}

animateNext();
@keyframes FadeIn { 
  0% { opacity:0; transform:scale(.1);}
  85% {opacity:1; transform:scale(1.05);}
  100% {transform:scale(1); }
}

.IconAnimate i {opacity:0;}
.IconAnimate i.show { opacity:1;animation: FadeIn 1s linear; animation-fill-mode:both;}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<div class="row IconAnimate">

  <div class="col-xs-12 col-sm-4 col-lg-2">
    <div><i class="fa fa-trademark fa-3x"></i>
      <h4><strong>TITLE 1</h4>
      <p>BLA BLA BLA</p>
    </div>
  </div>

  <div class="col-xs-12 col-sm-4 col-lg-2">
    <div><i class="fa fa-paint-brush fa-3x"></i> 
      <h4><strong>TITLE 2</strong></h4>
      <p>BLA BLA BLA</p>
    </div>
  </div>

</div>

PS: For demonstration purposes, I set the delay to just one second in both examples, just replace 1000 by 3000 to get 3 seconds.