Animating With Pure CSS and Webkit

If you’d like to see how animation on the web will evolve in the next few years, you only need to take a look at the animation techniques made possible by the Webkit HTML rendering engine. Though JavaScript is the preferred way of animating HTML elements, Webkit’s built-in animation capabilities outpace what’s currently offered by JavaScript animation libraries.

Obviously the animation techniques supported by Webkit may be entirely absent from other rendering engines, such as Gecko (Firefox) and Trident (Internet Explorer). Nevertheless, if a web presentation can be confined to just two major browsers, either Google Chrome or Apple Safari, then there are many interesting opportunities afforded by the Webkit animation features.


Before we start, we need to take a look at what properties Webkit introduces for animation. These are as follows:

  • scale, scaleX, scaleY – scale an object equally or in one dimension. To flip an object, set the scale to be negative
  • rotate – rotates an object around its center
  • translate, translateX, translateY – moves an object in two or one dimension. Use positive values to move the object right and down, negative values to move the object up and to the left
  • skew, skewX, skewY – skews an object in both or one dimension. You have to use the deg unit when specifying the skew amount

There are in fact a dozen or so other transform properties, but compatibility across even the Webkit browsers is sparse for them. For best results, use Chrome or Safari.

Transforming in CSS

Let’s create a demo page to test some of these properties. Here’s the code for it:

<html><head><style type="text/css">
body {margin:100px}
#demo {width:100px;height:100px;background:red}
<div id="demo"></div>

Opening the demo page in a browser, we see a simple red square. Now let’s rotate the square 45 degrees. Write the following CSS:

#demo { -webkit-transform: rotate(45deg)}

Here’s what you should get:

You can experiment with the other properties before moving on to the next section. Try skewing and rotating at the same time.

Animating Transforms

To get our red square to actually animate its rotation, we’ll need to add an additional Webkit-specific CSS rule:

#demo { -webkit-transition: -webkit-transform 0.5s ease-in-out}

The syntax of the transition property is simple: it’s the property being animated, the time it takes to animate it, and the easing parameter. You’ll note, however, that after adding this property, nothing has changed. To start the animation, we need to add an event where the animation is invoked. Let’s say we want the animation to start when the mouse moves over the red square. To do this, we simply add :hover to our transform declaration. The whole code looks like this:

#demo { -webkit-transition: -webkit-transform 0.5s ease-in-out}
#demo:hover { -webkit-transform: rotate(45deg)}

Here’s a time-lapse of the animation you should see when you mouse over the square:

You can animate more than one property at a time. This is called chaining properties. Doing this is very simple: just add the properties you want animated in the -webkit-transform rule separated by spaces. If we want to rotate and scale an element, we write the following:

-webkit-transform:rotate(45deg) scale(0.5)

What if we want to animate other CSS properties? Specifying each animated property in the -webkit-transition rule is laborious. Fortunately, we can declare all properties animatable. Here’s how it’s done:

#demo {-webkit-transition: all 1s ease-in-out}

Now let’s change the width of our red square and change its background to black. This is simple CSS:

#demo:hover {width:200px;background:#000;-webkit-transform:rotate(45deg) scale(0.5)}

Here’s a time-lapse of the animation created by these new rules:

As you can see, the animations offered by these simple controls are very useful, not only for UI animations, but also for actual motion graphics. It’s worth pointing out that Safari on the iPhone fully supports these kinds of animations, making fast, smooth, and efficient motions very accessible and independent of external JavaScript or Flash libraries.


Webkit also allows us to animate without triggers and with keyframes. To define a keyframe sequence, we need to create a keyframes rule, like so:

@-webkit-keyframes myAnimation { }

In the above example, myAnimation is the name of the animation sequence. This is useful as different animations can be swapped with one another at different points in the presentation’s progress. Let’s replicate our transition-based animation above with keyframes. Let’s call this animation rotate. Here’s the necessary code:

@-webkit-keyframes rotate {
	0% {width:100px;background:red;-webkit-transform:rotate(0deg)}
	100% {width:200px;background:black;
		-webkit-transform:rotate(45deg) scale(0.5)}}

As you can see above, things are fairly straightforward. The animation is split into as many keyframes, defined by percentages, as you like. To see this animation at work, get rid of the previous transition code and insert the following rule:

#demo {-webkit-animation: rotate 1s alternate;-webkit-animation-iteration-count:2}

Now when you load the page, the animation starts immediately. You can add a :hover to the above declaration, but watch what happens when you take your cursor off the box. The box immediately snaps back to its original state. For this reason, use keyframes and :hover judiciously.

The declaration itself is simple: there’s the animation name, how long it should take, and what the animation direction is. The animation iteration count specifies how many times the animation should run. With an alternate animation direction, the iteration count is effectively cut in half, so code accordingly.

Now let’s add a third keyframe, at 50%. At this keyframe, let’s set the background to yellow. The rule looks like this:


We see that the background does change to yellow, but the square only rotates and shrinks after the background’s changed. This is an important point in Webkit animation: be explicit about your keyframes. Let’s add the following:

width:150px;-webkit-transform:rotate(22.5deg) scale(0.75)

Looks good, but the animation’s a bit jerky. This is due to the default easing function. Webkit animates properties with an anticipation that they represent a “final” motion. We can alter this behavior by putting this line in the 0% portion of the animation:


Now the animation runs smoothly. Here’s a time-lapse:

Other Resources

This is just the tip of the iceberg. The whole Webkit animation topic doesn’t enjoy a wide enough audience yet, but there are some very interesting articles and demos out there (some of these require the nightly Webkit build):