213

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.

Don P
  • 60,113
  • 114
  • 300
  • 432
  • 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 – Ram G Athreya Nov 18 '14 at 03:44

6 Answers6

322

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

Example:

animation: rotate 1s, spin 3s;
isherwood
  • 58,414
  • 16
  • 114
  • 157
critical_error
  • 6,306
  • 3
  • 14
  • 16
  • 5
    what about different animation delays? – little tiny man Apr 26 '19 at 21:37
  • 4
    @little-tiny-man you can specify multiple `animation-delay` through coma as well, see [this answer](https://stackoverflow.com/a/49546937/2750743) – Klesun Aug 19 '20 at 12:13
  • 1
    @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. – carecki Mar 29 '21 at 09:24
  • 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 Apr 23 '21 at 19:18
  • @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. – Mikko Rantalainen Nov 18 '21 at 13:43
  • @MikkoRantalainen I am out of context since I was working on this long back. But you can check this animation I created. https://codepen.io/sgrpwr/pen/VwPqNra Hope it will helps! – sgrpwr Nov 19 '21 at 14:52
  • @sgrpwr That animation doesn't seem to include case where you use syntax `animation: X, Y;` where `X` and `Y` would be executed *serial* or in sequence instead of in parallel. That's the part I was interested to hear more. – Mikko Rantalainen Nov 19 '21 at 17:48
  • @MikkoRantalainen I don't think it would be possible to run multiple animations using a single line code. The only scalable genuine option I see is keyframes. – sgrpwr Nov 20 '21 at 18:25
  • @sgrpwr you wrote "No, this doesn't work. Two animations are running serially not parallely." above and I'm still trying to figure out what do you mean by that? – Mikko Rantalainen Nov 22 '21 at 14:00
274

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>
rnrneverdies
  • 15,243
  • 9
  • 65
  • 95
  • 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. – wharfdale Aug 17 '21 at 11:58
  • `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 – Sadisha Feb 01 '22 at 14:06
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/

Ray Waldin
  • 3,217
  • 1
  • 16
  • 14
5

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">
Frozenfrank
  • 61
  • 1
  • 7
Ram G Athreya
  • 4,892
  • 6
  • 25
  • 57
  • 2
    the user asekd for "at different speeds" – rnrneverdies Nov 18 '14 at 03:47
  • 1
    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. – Ram G Athreya Nov 18 '14 at 05:45
  • 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. – Justin Taddei Jan 07 '19 at 16:14
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>
Vitorino fernandes
  • 15,794
  • 3
  • 20
  • 39
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;
Oris Sin
  • 1,023
  • 1
  • 13
  • 33
Vanhaahr
  • 21
  • 1