43

I've run into some difficulty trying to play a CSS3 keyframe animation and have the relevant element stick at the last frame after the animation has completed. To my understanding, the property that I have to set for this to work should be animation-fill-mode, which should have the value of forwards; this doesn't do anything.

.animatedSprite { 
    .animation-name: sprite;
    .animation-duration: .5s;
    .animation-iteration-count: 1;
    .animation-direction: normal; 
    .animation-timing-function: steps(3); 
    .animation-fill-mode: forwards;
    //Vendor prefixes... }

This will just play the animation once and then go back to the first frame. I found an example of keyframe animations at JSFiddle ( http://jsfiddle.net/simurai/CGmCe/ ), and changing the fill mode to forwards and setting the iteration count to 1 wouldn't do anything there, either.

Any help would be greatly appreciated.

Joshua Jennings
  • 517
  • 1
  • 4
  • 13

4 Answers4

67

animation-fill-mode:forwards is the correct property to use. Is does not seem to work because the sprite image background has a default background-repeat:repeat, so the last frame you think you are seeing is actually the first frame of the repeated background image.

If you set

background: url("http://files.simurai.com/misc/sprite.png") no-repeat

animation: play .8s steps(10) forwards;

@keyframes play {
    from { background-position:    0px; }
    to { background-position: -500px; }
}

and run the demo the final frame is now blank - so forwards is doing what it should do. The second part of the solution is to change the final to and steps CSS properties to position the background correctly. So we really need the background to stop at -450px and use 9 steps.

-webkit-animation: play .8s steps(9) forwards;

@keyframes play {
    from { background-position: 0; }
    to { background-position: -450px; }
}

See demo - I only fixed the Chrome properties. Also here is the sample image in case the original disappears.

Waving sprite

.hi {
    width: 50px;
    height: 72px;
    background: url("https://i.stack.imgur.com/ilKfd.png") no-repeat;
    
    -webkit-animation: play .8s steps(9) forwards;
       -moz-animation: play .8s steps(10) infinite;
        -ms-animation: play .8s steps(10) infinite;
         -o-animation: play .8s steps(10) infinite;
            animation: play .8s steps(9) forwards;
}

@-webkit-keyframes play {
   from { background-position:    0px; }
     to { background-position: -450px; }
}

@-moz-keyframes play {
   from { background-position:    0px; }
     to { background-position: -500px; }
}

@-ms-keyframes play {
   from { background-position:    0px; }
     to { background-position: -500px; }
}

@-o-keyframes play {
   from { background-position:    0px; }
     to { background-position: -500px; }
}

@keyframes play {
   from { background-position:    0px; }
     to { background-position: -450px; }
}
<div class="hi"></div>
andyb
  • 43,435
  • 12
  • 121
  • 150
  • 1
    Thanks @Neil - I have updated and embedded the demo now – andyb Sep 01 '15 at 12:26
  • Perfect example @andyb. Thank you – Ana DEV Mar 27 '17 at 12:56
  • Thanks, the forwards property helps but in my case it still wasn't enough, so I had to shorten the width by the width of the last frame and then decrease the steps number by one – Mike Nov 24 '20 at 11:32
2

Change 'infinite' to '1' in the css, this fixes it for me

Adam Moseley
  • 199
  • 1
  • 10
  • 2
    Hey Adam, this returns it to the first frame for me (After additionally adding the fill-mode: forwards property), as opposed to stopping on the last. – Joshua Jennings Oct 21 '13 at 21:29
0

just add

animation: mymove .8s forwards;

here 'mymove' is name of my keyframe

example:

<html>
<head>
<style> 
div {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
 animation: mymove .8s forwards;
}

@keyframes mymove {
  from {top: 0px;}
  to {top: 200px;}
}
</style>
</head>
<body>

<h1>The @keyframes Rule</h1>

<div></div>

</body>
</html>
jo3
  • 1
  • 1
-2

The following code will make the transition stay on the last frame:

-webkit-timing-function:ease;
-webkit-iteration-count:1;
Ulfalizer
  • 4,664
  • 1
  • 21
  • 30
vijay
  • 1
  • 2
    This is wrong, it's `forwards`, not the iteration count. If you do iteration at 1, at the end of the last frame it will revert back. – NiCk Newman Jul 13 '15 at 21:20