236

How can I have two CSS animations playing at different speeds?

  • The image should be rotating and growing at the same time.
  • The rotation will cycle every 2 seconds.
  • The growth will cycle every 4 seconds.

Example Code:

.image {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 120px;
    height: 120px;
    margin:-60px 0 0 -60px;
    -webkit-animation:spin 2s linear infinite;
    -webkit-animation:scale 4s linear infinite;
}

@-webkit-keyframes spin { 
    100% { 
        transform: rotate(180deg);
    } 
}

@-webkit-keyframes scale {
    100% {
         transform: scaleX(2) scaleY(2);
    }
}

http://jsfiddle.net/Ugc5g/3388/ - only one animation (the last one declared) plays.

1
  • Should the image scale while it is rotating? The answer I have provided doesn't but if that is what you need then it can be tweaked to do that Commented Nov 18, 2014 at 3:44

8 Answers 8

361

You can specify multiple animations--each with their own properties--with a comma.

Example:

animation: rotate 1s, spin 3s;
Sign up to request clarification or add additional context in comments.

9 Comments

what about different animation delays?
@little-tiny-man you can specify multiple animation-delay through coma as well, see this answer
@little-tiny-man delays can be specified as part of animation shorthand form, e.g. rotate 1s 0.5s, spin 3s 10s for 0.5 and 10s delays respectively.
No, this doesn't work. Two animations are running serially not parallely. Here it looks like working because delays are very small if you increase the duration you will see the difference.
@sgrpwr Do you have an example somewhere? When multiple animations have been defined for a single element, those should apply in parallel, not in sequence (or serial). Note that if multiple animations modify the same property in parallel it may appear to behave incorrectly because only the last effect will stay.
|
281

TL;DR

With a comma, you can specify multiple animations each with their own properties as stated in the CriticalError answer below.

Example:

animation: rotate 1s, spin 3s;

Original answer

There are two issues here:

#1

-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;

The second line replaces the first one. So, has no effect.

#2

Both keyframes applies on the same property transform

As an alternative you could to wrap the image in a <div> and animate each one separately and at different speeds.

http://jsfiddle.net/rnrlabs/x9cu53hp/

.scaler {
    position: absolute;
    top: 100%;
    left: 50%;
    width: 120px;
    height: 120px;
    margin:-60px 0 0 -60px;
    animation: scale 4s infinite linear;    
}

.spinner {
    position: relative;
    top: 150px;
    animation: spin 2s infinite linear;
}


@keyframes spin { 
    100% { 
        transform: rotate(180deg);
    } 
}

@keyframes scale {
    100% {
         transform: scaleX(2) scaleY(2);
    }
}
<div class="spinner">
<img class="scaler" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">
<div>

2 Comments

Can you add a delay between the two animations in your example? animation: rotate 1s, spin 3s;. So rotate runs, then pause for X seconds, then run spin animation.
animation: rotate 1s forward 5s, spin 3s forward 4s; In this, 5s is the delay for rotate animation and 4s is the delay for spin animation. @wharfdale
43

You can indeed run multiple animations simultaneously, but your example has two problems. First, the syntax you use only specifies one animation. The second style rule hides the first. You can specify two animations using syntax like this:

-webkit-animation-name: spin, scale
-webkit-animation-duration: 2s, 4s

as in this fiddle (where I replaced "scale" with "fade" due to the other problem explained below... Bear with me.): http://jsfiddle.net/rwaldin/fwk5bqt6/

Second, both of your animations alter the same CSS property (transform) of the same DOM element. I don't believe you can do that. You can specify two animations on different elements, the image and a container element perhaps. Just apply one of the animations to the container, as in this fiddle: http://jsfiddle.net/rwaldin/fwk5bqt6/2/

1 Comment

Thanks for specifying we can do multiple animations since we separate name with commas.
6

You cannot play two animations since the attribute can be defined only once. Rather why don't you include the second animation in the first and adjust the keyframes to get the timing right?

.image {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 120px;
    height: 120px;
    margin:-60px 0 0 -60px;
    -webkit-animation:spin-scale 4s linear infinite;
}

@-webkit-keyframes spin-scale { 
    50%{
        transform: rotate(360deg) scale(2);
    }
    100% { 
        transform: rotate(720deg) scale(1);
    } 
}
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">

3 Comments

the user asekd for "at different speeds"
It is at different speeds the rotate happens in 2 secs while the scale happens in 4 seconds since writing two animation statements does not work I have taken care of timing via keyframes.
While it is true that you cannot play two transform animations at the same time (because one transform would overwrite the other), it is not correct to say "You cannot play two animations since the attribute can be defined only once." See the accepted answer about using comma-separated values with animations.
2

you can try something like this

set the parent to rotate and the image to scale so that the rotate and scale time can be different

div {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  -webkit-animation: spin 2s linear infinite;
}
.image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  -webkit-animation: scale 4s linear infinite;
}
@-webkit-keyframes spin {
  100% {
    transform: rotate(180deg);
  }
}
@-webkit-keyframes scale {
  100% {
    transform: scale(2);
  }
}
<div>
  <img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120" />
</div>

Comments

2

Turn these 2 lines:

-webkit-animation:spin 2s linear infinite;
-webkit-animation:scale 4s linear infinite;

into:

 -webkit-animation: spin 2s linear infinite, scale 4s linear infinite;

Comments

0

Using some different layered <div>'s we can set each of the animations individually. Below is my super simple implementation :)

.layer1 {
    animation: spin 50s;
}

.layer2{
    animation: move-in-circle 20s;
}

@keyframes move-in-circle {
    0% {
        transform: rotate(0deg) translateX(40vw) rotate(0deg);
    }
    100% {
        transform: rotate(360deg) translateX(40vw) rotate(-360deg);
    }
}

@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}
<div class="layer1">
    <div class="layer2">
      <p>Hello World</p>
    </div>
 </div>

Comments

0

Depending on the situation, you could set up a single keyframe to reflect the different rates. In your case it spins twice before scaling is done. So have a keyframe defined at 50% for rotate. This only works for the least common multiple, but it might be a simpler way to tackle the same problem. Mixing with multiple CSS classes is more flexible and gives you greater control. But I thought I'd mention a quick & dirty solution.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.