Design, CG Graphics & Inspiration
Sprite animation in CSS3

Sprite animation in CSS3

Sprite animation – is one of those things that, for all its primitiveness is still working successfully and is being applied in computer graphics and games for more than a quarter century. Even 3D games have sprites – for example, billboard explosions. Sprite animation is used in many browser-and flash-games, because it is very simple and does not require high performance – all you need is to change the frames and that’s it! And with the advent of animation in CSS3 it has become possible to use sprites on your pages without javascript.

I would like to mention that the described method below works so far only for webkit-browsers. So, let’s take a simple sprite from three frames:
sprite in Sprite animation in CSS3

All we have to do with it is to put the background in a div and change its background-position in some time. It seems to be simple:
Copy Source | Copy HTML
[code]
.sprite
{
position: absolute;

left: 50%; /* sprite’s position */
top: 33%;
width: 32px; /* size */
height: 32px;

margin: -16px 0 0 -16px; /* just to place it in a centre */

background: url(sprite.png) no-repeat 0 0; /* background */

-webkit-animation-name: sprite;
-webkit-animation-duration: .3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}

/* sprite animation*/
@-webkit-keyframes sprite
{
/* you need to move sprite’s background three times, on the fourth we get back to 0 */
0%
{
background-position: -0px 0;
}
33%
{
background-position: -32px 0;
}
66%
{
background-position: -64px 0;
}
100%
{
background-position: -0px 0;
}
}[/code]

Advertisement

But alas! As a result, we see only rubbish. The picture is moving smoothly and not choppy in a longitude of a shot. Let’s try to improve the situation, by making long intervals and rapidly switching between the frames:

Copy Source | Copy HTML
[code]
@-webkit-keyframes sprite
{
0%
{
background-position: -0px 0;
}
33.332%
{
background-position: -0px 0;
}
33.334%
{
background-position: -32px 0;
}
66.665%
{
background-position: -32px 0;
}
66.667%
{
background-position: -64px 0;
}
99.999%
{
background-position: -64px 0;
}
100%
{
background-position: -0px 0;
}
}
[/code]

The code is fairly long, and we are almost satisfied with the result, but there is a small “but” in this case: in small intervals we can see some spurts. To get a fully correct animation we must resort to other clever features of CSS3: to increase the size. To do this, set the frame width and height of 1 pixel and using the transform property of the sprite increase it to 32 pixels.

Copy Source | Copy HTML
[code].sprite
{
position: absolute;

left: 50%;
top: 33%;
width: 1px; /* the frame width and height should be of 1 pixel */
height: 1px;

margin: -16px 0 0 -16px; /* the increase via transform doesn’t influence the margin */

background: url(sprite.png) no-repeat 0 0;
background-size: 3px 1px; /* we also decrease the size of a background */

-webkit-animation-name: sprite;
-webkit-animation-duration: .3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-transform: scaleX(32) scaleY(32); /* let’s increase the size of the element*/
-webkit-transform-origin: top left;
}

@-webkit-keyframes sprite
{
/* then we should move the background for 1 pixel every time */
0.000%
{
background-position: -0px 0;
}
25.000%
{
background-position: -1px 0;
}
50.000%
{
background-position: -2px 0;
}
/* frankly speaking, I didn’t get the idea, why should we move it */
/* for 1 more pixel (because it should be */
/* the empty frame). otherwise it won’t show us all */
/* animation frames. */
75.000%
{
background-position: -3px 0;
}
100.000%
{
background-position: -0px 0;
}
}
[/code]

Now the result is completely consistent with our expectations. The animation is normal, smooth and without any spurts. For the generation of the key frames you can use this function:

[code]function generateKeyframes($count, $sprite_width)
{
$result = '';
$count++;
for ($i = 0; $i <= $count; $i++)
{
$result .= sprintf("\t%.3f%%\n\t{\n\t\tbackground-position: -%dpx 0;\n\t}\n", $i * 100. 0 / $count, ($i % $count) * $sprite_width);
}
return $result;
}[/code]

Unfortunately, this method isn’t being used widely in practice, since it works only in browsers such as Webkit- Chrome or Safari. In Firefox, the animation will remain smooth, Opera only shows the first frame, but in IE it does not work. So that the animation with the use of Javascript and Flash will keep their positions for quite some time.

  • ertaquo,
  • July 7, 2011

SHARE THIS POST

Subscribe for the hottest posts

Subscribe to our email newsletter for useful tips and freebies.

  • http://www.the-triumph.com Web Design Company Mumbai

     Nice work.

  • http://www.derby-webdesign.co.uk Kevin

    Great work, I’ve recently been looking at sprites and this has helped me further my knowledge. Many Thanks =)

  • http://www.eversfieldorganic.co.uk/dept/eversfield-organic-monthly-meat-boxes_d015.htm Organic Meat Boxes Monthly

    Great post. I am a regular visitor of your site and appreciate you taking the time to maintain the excellent content. I will be a frequent visitor for a long time.

  • http://twitter.com/OverclockedTim Timothy Jones

    Ok, so this was awesome and very helpful.  If may say so, an example might make it even more helpful :D

  • RedRooster

    Any Idea how to harware accellerate this thing on iOS?

  • http://maderogue.com/ Patrick Kim

    -webkit-transform: translateZ(0); Here’s how you hardware accelerate the thing. 

    One more caveat, I noticed on CSS sprites is that if you zoom in, the step animation goes nuts until you refresh the page.