CSS be used for more than the mere transformation of elements; it can also be used to animate them.
This new ability in CSS definitely rubs up against JavaScript, which has traditionally been used for animation on web pages. However, animation still falls under the purview of CSS: remember, CSS is about the appearance of elements. That includes animation. The domain of JavaScript is behaviour, which is now defined at a deeper and (in some ways) more basic level. If you want to highlight alternating rows of a table, that’s CSS (the way something looks). If you want the data in the table to be sortable based on different criteria, that is JavaScript (the way something acts on a page).
The principles of CSS animation are very simple:
- Set up the default state of the element in CSS.
- Define how the element will appear in its final state.
- Write a transition, triggered by an event.
- Specify the period of time for the transition. You can also set what properties of the element should change during the animation, and the rate of change.
You can transition most every CSS property you can imagine, and some you likely cannot. Animating properties like opacity
, to create fade in and fade out effects, or CSS3 transforms, like rotate
, translate
and scale
, are obvious… but you can also animate color
, background
, shadow
, width
, height
, line-height
and font-size
, to name just a few.
Let’s say we have an image with an id
of biplane
on the page. We want to bring the page to life by having this image rotate slightly when the user places their mouse over it. If we were to do this without animation, but still in CSS, the code would be very simple (at least without vendor prefixes):
img#biplane {
width: 500px;
height: 415px;
border: 20px solid #ffe;
box-shadow: 10px 10px 3px rgba(0, 0, 0, 0.3);
}
img#biplane:hover {
transform: rotate(7deg);
}
This works fine, except for the fact there is no transition between one state and the other: the image “jerks” when it rotates, as it moves in a single step. Let’s smooth this transition with a little more CSS. At the very basic level, we need to specify only one property: how long it takes for the element to animate between its original state and the new orientation, a draft property called transition-duration
:
img#biplane:hover {
transition-duration: 1s;
transform: rotate(7deg);
}
That’s it. Up-to-date browsers will transition the rotation of the image over 1 second. Those closely observing the movement of the image will have noticed that the animation is automatically eased in and out: the rotation starts off slow, speeds up to reach a terminal velocity, and then slows down before it comes to rest (increasing the amount of rotation and/or the time taken to do so may enhance your perception of this).
Animation in CSS has easing: built-in organic, natural motion. If you want a more “mechanical” feel to the motion, you can achieve it by changing a property known as the transition timing function
to linear
:
img#biplane:hover {
transition-duration: 1s;
transition-timing-function: linear;
transform: rotate(7deg);
}
It’s possible to set the timing function to other values, or even to mathematically plot out Bezier function easing curves:
transition-timing-function: ease | linear | ease-in|ease-out | ease-in-out |cubic-bezier(<number>, <number>, <number>, <number>)
Finally: if you’ve used the code above, you’ll see that the transition works on mouseover, but not when you move the mouse off the element: when that occurs, the image jerks back to its original position. To solve this problem, we do something that may appear counter-intuitive at first: we move the transition information out of the :hover
state declaration and into the default state. At the same time, we should recognize that this code is getting a little long, even for CSS: transition properties, like everything else, can be shortcut. Let’s move the code and re-write it at the same time:
img#biplane {
width: 500px;
height: 415px;
border: 20px solid #ffe;
box-shadow: 10px 10px 3px rgba(0, 0, 0, 0.3);
transition: all 1s ease-in-out;
}
img#biplane:hover {
transform: rotate(7deg);
}
Perhaps the easiest way to think of this is that we previously indicated that the transition only occurred on the way to the hover state; with this change, we are indicating that the transition affects all effects, over a 1 second period, using ease-in and ease-out, both to and from the default state.
Photograph of Spartan C3 biplane provided by San Diego Air & Space Museum archive, licensed under Creative Commons.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.