How to Make Good Use of CSS3 Animations: Tutorial, Sample Codes, and Examples

Article written by: Rochester Oliveira
  • Website Design
  • Aug 28, 2013

When we use JS and jQuery we have full control over the animations and we can create some awesome effects, but the price is quite high. Processing time, cross-browser compatibility (mobile devices, for example, are quite different when it comes to JS) and the code complexity itself are points that we should keep in mind while creating animated interfaces.

So, today we’ll see how to avoid JS by using CSS Animations and Transitions. We’ll discuss from the very basic steps to some awesome effects, like accordion panels and animated sub-menus.

Grab a seat, you notepad and a real browser (anything but IE) and let’s get started.

Warming up

We have quite a few advantages (and disadvantages as everything in our lives) in using CSS animations. If you need to sell those to your boss or client, this is what you should keep in mind:

  • They are potentially faster, since they can make use of hardware acceleration (as HTML5 implementations)
  • They’ll perform better in mobile devices and won’t need specific code to track touch events
  • JS needs to be interpreted by the browser and the possibilities to break the browser are much bigger. So when CSS fails, it fails silently while JS can break the entire page
  • They have quite a good browser support (this site will help you checking specific stats on that: )

Examples of CSS3 Animations

Before we get started on the meat of this post, let’s look at some beautiful animations made in pure CSS.

Pure CSS Twitter Fail Whale

Animated Failed Whale

 Made by Steven Dennis, see this in action.

Pure CSS Scrolling Coke Can
CSS 3 Animation Examples: Scrolling Coke Can

Made by Roman Cortes, see this in action.

Pure CSS Walking Man

CSS 3 Animation Examples: The Walking Man

 Made by Andrew Hoyer, see this in action.

Getting Your Hands Dirty

Let’s start the code. We’ll use a lot the CSS pseudo classes to trigger the animation. To be honest, a lot of developers recommend you using JS to activate and de-activate animations, but here we’ll see the easier way:

#test {
	background: red;
#test:hover {
	background: green;
#test:active {
	background: blue;
#test:target {
	background: black;

We have a few other pseudo-classes to use, but you’ve got the idea! So here is what happens if you click the #test element (assuming it’s a link):

  • Normal state: Background will be red
  • Hover: When the mouse enters element area it’ll have a green background
  • Active: When you click the cursor on it and while the mouse button is still pressed the background color will be blue
  • Target: When current page has the #test in the URL this element will be black

Each one of these can be used for CSS animations, for example you could create 2 links to activate and deactivate the CSS animation making use of the target pseudo element with this code:

<a href='#test'>activate</a>
<a href='#'>deactivate</a>

CSS Transitions

CSS transition will change from the initial to the end state smoothly. So you’ll define in the main selector using the “transition” property the time and each property that will be affected and how the animation should be. Let’s see an example:

.test {
	/*transition-property duration timing-function,*/
	color: blue;
	transition: color 2s, font-size 2s ease-out;
.test:hover {
	color: red;
.test:active {
	font-size: 200%;

When you hover the .test element it’ll change gradually the color from blue to red (what a nice palette, huh?). When you click the element, the font size will gradually increase to 200% of the default font size.

We have also the “transition timing” property, set as ease-out, that how the “time” available for the animation will be spent. Here are the possible values:

  • Linear: Same speed from the beginning to the end
  • Ease-in: Slow start
  • Ease-out: Slow end
  • Ease: Slow start, fast in the middle, then slow end
  • Ease-in-out: Slow start, slow end
  • Cubic-bezier(a,b,c,d): Custom speed

The cubic Bezier function will create a custom animation with 4 numbers that varies from 0 to 1, representing the mathematical curve for animation speed X duration.

For better browser compatibility you should consider using the vendor prefixes for opera, Firefox, and webkit like this:

div {
	width: 400px;
	-o-transition: width 2s;
	-moz-transition: width 2s;
	-webkit-transition: width 2s;
	transition: width 2s;

Also, you could make use of the media queries to define different transitions depending on browser width (mobile devices, tablets). This is a simple example:

body {
	font-size: 1em;
@media screen and (max-width: 800px) {
	body {
		font-size: 0.8em;
@media screen and (max-width: 400px) {
	body {
		Font-size: 0.7em;

Here the font size will be changed suddenly when you increase the browser width. This code will prevent that from happening, giving a much smoother transition:

body {
	-o-transition: font-size .5s linear;
	-moz-transition: font-size .5s linear;
	-webkit-transition: font-size .5s linear;
	transition: font-size .5s linear;

You could use this also if you have different displays or sizes for portrait / landscape, if you want to change widths, colors, paddings, menu display.

CSS Animation – The Real Fun Starts

The animation is a sequence of transitions defined in a single selector. To define CSS animations you’ll need to follow 2 steps.

The @keyframe rule is used to define a sequence of animation steps, and it’s defined by a unique name and the styles that describe how this animation works. As usual we’ll need some vendor prefixes, like in this example:

/*the same code for each vendor*/
@-o-keyframe my-animation { ...
@-moz-keyframe my-animation { ...
@-webkit-keyframe my-animation { ...
/*animation name*/
@keyframe my-animation {
	/*frame selector*/
	0% {
		/*frame style*/
		Left: 0px;
		Top: 0px;
	25% {
		Left: 200px;
		Top: 0px;
	50% {
		Left: 200px;
		Top: 200px;
	75% {
		Left: 0px;
		Top: 200px;
	100% {
		Left: 0px;
		Top: 0px;

So, each style is defined by the frame / timeframe (like those frames from a flash animation) as a percentage and the styles that should be applied there. This keyframe, for example says that the element will move to the left, then top, then right, then bottom.

After you’ve followed the step 1 and created your keyframe you can actually apply it to an element. Then we’ll use pretty much the same logic as we’ve done with the CSS transition, the difference is that now our “transition” is a much complex animation.

To apply it we’ll use the animation property and it has 7 sub-properties:

  • Name: that unique identifier
  • Duration: How long will it take from 0% to 100%
  • Timing-function: pretty much the same as the transition timing function
  • Delay: How long will it take to start the 0%
  • Iteration-count: How many repetitions will we have(“infinite” for a infinite loop)
  • Direction: normal or alternate (reverse)
  • Play-state: if the animation is running or paused

This will apply our animation to the #test element when it is the page’s target:

#test:target {
	/*animation-name | duration | timing-function | delay  |iteration-count | direction | play-state */
	animation: my-animation 10s linear 0s infinite normal running;

With this in mind we can create a few awesome examples.

CSS Only Accordion

We’ll create collapsible panels making use of the CSS animations. Here is the basic HTML structure:

<div class="accordion">
	<a href="#tab1">Tab 1</a><div id="tab1"><p>TEXT 1</p></div>
	<a href="#tab2">Tab 2</a><div id="tab2"><p>TEXT 2</p></div>
	<a href="#tab3">Tab 3</a><div id="tab3"><p>TEXT 3</p></div>

This will just create the panels and the link that will trigger each one of them. And here is where the magic happens:

/* any div that is inside of the accordion*/
.accordion div  {
	/*is hidden by default */
	height: 0;
	overflow: hidden;
	/* the black magic */
	transition: height 1s;
	/*when the mentioned div is the target */
	.accordion div:target {
		/*height:auto won’t work, but this will work fine*/
		height: 80px;

Pretty simple, huh? And you’ve spent your entire life using JS for this? :)

CSS Only Menu with Submenus

And this is another rather simple application. You certainly have a navigation menu in your site, and often we need to use some submenus there. The best way to show and hide items is using jQuery, right? Well, think again after you test this code:

		<li><a href='#item1'>Item 1</a><div><ul>
			<li><a href='#item11'>Item 1.1</a></li>
			<li><a href='#item12'>Item 1.2</a></li>
		<li><a href='#item2'>Item 2</a><div><ul>
			<li><a href='#item21'>Item 2.1</a></li>
			<li><a href='#item22'>Item 2.2</a></li>

And the wizardry begins here:

a {
	/* just making the links a tad better */
	display: block;
	padding: 4px;
nav {
	text-align: center;
	/* any menu (including the main one)*/
	nav ul {
		display: inline-block;
		list-style: none;
		nav>ul>li {
			/* horizontal items (vertical will work fine too) */
			float: left;
			nav li div {
				/*collapsing any sub-menu*/
				height: 0;
				overflow: hidden;
				/* Houdini feelings */
				transition: height 1s;
			nav li:hover>div {
				height: 56px;

Summing Up

This is certainly just a getting started guide. There are a lot of other cool effects that can be done using CSS only animations and a lot of things certainly yet to come.

So, have you used this before? Can you think of another good application for CSS animations? Share your thoughts using the comments!

Article by Rochester Oliveira

I'm a web designer and entrepreneur from Itajubá (MG), Brasil. I love writing about obscure topics and doing some cool stuff.

Get connected: