WAIT! Animate

CSS doesn't provide a property to pause an animation before it loops around again. Yes, there's animation-delay but this simply denotes a delay at the very start of the animation, when the element is first shown. WAIT! Animate calculates updated keyframe percentages given a wait time meaning you can insert a delay between each animation iteration using pure CSS, without JavaScript.


SCSS Mixin

@mixin waitAnimate($options: ()) {
  $options: map-merge((
    animationName: waitAnimate,
    duration: 1,
    waitTime: 0,
    timingFunction: linear,
    iterationCount: infinite
  ), $options);

  $name: map-get($options, animationName);
  $kf: map-get($options, keyframes);
  $kfLength: length($kf);
  $duration: map-get($options, duration);
  $waitTime: map-get($options, waitTime);
  $timingFunction: map-get($options, timingFunction);
  $iterationCount: map-get($options, iterationCount);
  $counter: 1; // index of 'each'

  @keyframes #{$name} {
    @each $frame, $prop in $kf {
      #{$frame * $duration / ($duration + $waitTime)}% {
        @each $k, $v in $prop {
          #{$k}: #{$v}
        }
      }
      // if last in loop and waitTime is not 0, add the last frame as 100% (this is what creates the pause)
      @if $counter == $kfLength and $waitTime > 0 {
        100% {
          @each $k, $v in $prop {
            #{$k}: #{$v}
          }
        }
      }
      $counter: $counter+1;
    }
  }

  .#{$name} {
    animation: #{$name} #{$duration + $waitTime}s #{$timingFunction} #{$iterationCount};
  }
}
        

Include:

@include waitAnimate(
  (
    animationName: animName,
    keyframes: (
      0: (
        transform: scale(1),
        background-color: blue
      ),
      50: (
        transform: scale(2),
        background-color: green
      ),
      100: (
        transform: scale(3),
        background-color: red
      )
    ),
    duration: 2,
    waitTime: 1,
    timingFunction: ease,
    iterationCount: infinite
  )
);
            

Output:

@keyframes animName {
  0% {
    transform: scale(1);
    background-color: blue;
  }
  33.33333333% {
    transform: scale(2);
    background-color: green;
  }
  66.66666667% {
    transform: scale(3);
    background-color: red;
  }
  100% {
    transform: scale(3);
    background-color: red;
  }
}

.animName {
  animation: animName 2s ease infinite;
}
            

You'll notice that you need to change your keyframes rule to a SASS map object. I was unable to find a solution that could manipulate a standard keyframes rule. If you know of a way to do this, please let me know.

@include waitAnimate((options));

Option Description Type Required? Default
animationName The class name of your animation. String No waitAnimate
keyframes The 0% to 100% animation rule. SASS map object Yes
duration The length of the animation in seconds (wait time will be added to this). Number No 1
waitTime The amount of pause time in seconds at the end of the animation. Number No 0
timingFunction The speed curve of the animation. String No linear
iterationCount The number of times the animation should be played. String No infinite