Abhi
Abhi

Reputation: 4271

Why is my bounce animation so jumpy instead of smooth?

I needed to implement infinite bounce effect using pure CSS, so I referred this site and ended up doing this.

.animated {
  -webkit-animation-duration: 2.5s;
  animation-duration: 2.5s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
} 

@-webkit-keyframes bounce {
  0%, 20%, 40%, 60%, 80%, 100% {-webkit-transform: translateY(0);}
  50% {-webkit-transform: translateY(-5px);}
} 

@keyframes bounce { 
  0%, 20%, 40%, 60%, 80%, 100% {transform: translateY(0);}
  50% {transform: translateY(-5px);}
} 

.bounce { 
  -webkit-animation-name: bounce;
  animation-name: bounce;
}

#animated-example {
    width: 20px;
    height: 20px;
    background-color: red;
    position: relative;
    top: 100px;
    left: 100px;
    border-radius: 50%;
}

hr {
    position: relative;
    top: 92px;
    left: -300px;
    width: 200px;
}
<div id="animated-example" class="animated bounce"></div>
<hr>

Now, my only problem is the bouncing element takes a longer rest before it starts bouncing again. How can I make it bounce smoothly just like the bounce effect we get by using jQuery.animate?

Upvotes: 26

Views: 144355

Answers (3)

GerritElbrink
GerritElbrink

Reputation: 352

In case you're already using the transform property for positioning your element (as I currently am), you can also animate the top margin:

.ball {
  animation: bounce 1s infinite alternate;
  -webkit-animation: bounce 1s infinite alternate;
}

@keyframes bounce {
  from {
    margin-top: 0;
  }
  to {
    margin-top: -15px;
  }
}

Upvotes: 5

Persijn
Persijn

Reputation: 15000

Here is code not using the percentage in the keyframes. Because you used percentages the animation does nothing a long time.

  • 0% translate 0px
  • 20% translate 0px
  • etc.

How does this example work:

  1. We set an animation. This is a short hand for animation properties.
  2. We immediately start the animation since we use from and to in the keyframes. from is = 0% and to is = 100%
  3. We can now control how fast it will bounce by setting the animation time: animation: bounce 1s infinite alternate; the 1s is how long the animation will last.

.ball {
  margin-top: 50px;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  background-color: cornflowerblue;
  border: 2px solid #999;
  animation: bounce 1s infinite alternate;
  -webkit-animation: bounce 1s infinite alternate;
}
@keyframes bounce {
  from {
    transform: translateY(0px);
  }
  to {
    transform: translateY(-15px);
  }
}
@-webkit-keyframes bounce {
  from {
    transform: translateY(0px);
  }
  to {
    transform: translateY(-15px);
  }
}
<div class="ball"></div>

Upvotes: 31

Harry
Harry

Reputation: 89780

The long rest in between is due to your keyframe settings. Your current keyframe rules mean that the actual bounce happens only between 40% - 60% of the animation duration (that is, between 1s - 1.5s mark of the animation). Remove those rules and maybe even reduce the animation-duration to suit your needs.

.animated {
  -webkit-animation-duration: .5s;
  animation-duration: .5s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
  -webkit-animation-timing-function: linear;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
}
@-webkit-keyframes bounce {
  0%, 100% {
    -webkit-transform: translateY(0);
  }
  50% {
    -webkit-transform: translateY(-5px);
  }
}
@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}
.bounce {
  -webkit-animation-name: bounce;
  animation-name: bounce;
}
#animated-example {
  width: 20px;
  height: 20px;
  background-color: red;
  position: relative;
  top: 100px;
  left: 100px;
  border-radius: 50%;
}
hr {
  position: relative;
  top: 92px;
  left: -300px;
  width: 200px;
}
<div id="animated-example" class="animated bounce"></div>
<hr>


Here is how your original keyframe settings would be interpreted by the browser:

  • At 0% (that is, at 0s or start of animation) - translate by 0px in Y axis.
  • At 20% (that is, at 0.5s of animation) - translate by 0px in Y axis.
  • At 40% (that is, at 1s of animation) - translate by 0px in Y axis.
  • At 50% (that is, at 1.25s of animation) - translate by 5px in Y axis. This results in a gradual upward movement.
  • At 60% (that is, at 1.5s of animation) - translate by 0px in Y axis. This results in a gradual downward movement.
  • At 80% (that is, at 2s of animation) - translate by 0px in Y axis.
  • At 100% (that is, at 2.5s or end of animation) - translate by 0px in Y axis.

Upvotes: 53

Related Questions