Advertisement

jQuery Animations: A 7-Step Program

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

A dash of animation can spruce up a dull interface. In this tutorial, you'll learn how to do it the right way with jQuery.


A Word From the Author

Animation: a concept which often evokes divisive reactions from people. Some swear by its usefulness, whilst others rage at its overuse. Nevertheless, animations, when used right, often spruce up a user interface, and make it feel much more snappy and clean. In this tutorial, we are going to start with a little jQuery basics, then learn how to create our first animation, and then on to building the effect and finally crafting something that will be of actual real world use.

Interested? Let's start right away! Please do note that as this is geared towards the beginner, I might harp a little too much on some parts. Bear with me. In case you are curious, check out the first part of the demo for the simple effect we'll be building today.


Step 1: jQuery Basics

jQuery is a JavaScript library which intends to make it easier for you, a developer, to construct better, feature rich, interactive web sites and user interfaces with as few lines of code as possible.

A typical line of code looks like so:

$(DOM Element).something();

Let's take a look at each part:

  • $ - Shorthand for the jquery object. Use jquery in case you are using another framework in the same page, as in: jquery(DOM Element).something();
  • (DOM Element) - The element you want to do something with. This is one of jQuery's ace in the hole. You can use CSS selectors to obtain an element. Any declaration which works in a CSS document can be utilized here. IDs, classes, pseudo classes, anything.
  • something() - The thing you want to do to the obtained element. This can be anything from hiding an element to making an AJAX call to an event handler.

Here, we are going to just stick with animation and effects related functionality.


Step 2: Using the Baked-in Effects

jQuery provides a ton of built in methods you can use right out of the box. These include methods for showing/hiding elements with a number of variations including sliding the element and fading the element in and out. You also get to use a number of toggle methods which toggle the visibility of the element in question.

Before we take a look at each of these methods, here is the general format for calling each method:

$("#element").effect([speed, callback]);

Following the general jQuery paradigm, we initially target the required element using CSS selectors. Next, we just call any of the built in methods.

While, most of the methods can be called passing no parameters, often you'd want to customize it's functionality. Each methods takes at least the speed and callback parameters.

speed denotes the duration, in seconds, of the animation. You can pass in strings including slow, normal or fast or you can be more precise and set the time in milliseconds.

callback is a function which gets executed once the animations completes. You can use it to do anything, make an AJAX call silently in the background, update another part of the user interface and so on. Your imagination is the limit.

Here is a list of the functions bundled with jQuery:

  • show/hide - Methods to show or hide an element. Takes speed and a callback as parameters.
  • toggle - Method which manipulates the display of the element depending on the current state of the element i.e. if it is hidden, it is displayed and vice versa. Uses the show or hide methods.
  • slideDown/slideUp - Self explanatory. Varies the height of the element to create a sliding animation to reveal or hide an element.
  • slideToggle - Same as the toggle method except that it use the slideDown/slideUp methods to reveal or hide elements.
  • fadeIn/fadeOut - Varies the opacity of the element in question to create a fade effect.
  • fadeTo - Alters the opacity of the element to match the passed in value. Obviously, it takes an additional opacity parameter where 0 is completely transparent and 1 is completely opaque.

As an additional feature, the toggle method mentioned above has an alternative implementation where it takes an expression as a parameter to decide whether to display or hide an element.

For example, if you want to toggle only list elements which have a effect class, your code would look like:

      $("li").toggle( $(this).hasClass("effect") );

To put it simply, the toggle functions checks the expression passed to it and if it is true, it is toggled. Else, it is left alone. The expression we've passed here checks whether the element has a specific class.


Step 3: Building a Custom Animation

Often, the built in methods don't quite fit your needs in which case you'd definitely want to build your own custom effects. jQuery lets you do that too. Quite easily, actually.

To make a custom animation effect, you make use of the animate method. Let me show you.

$("#somelement").animate({property: value}, [speed, callback] );

The animate method is just like any other method in that it is invoked the same way. We acquire an element and then pass some parameters to it. The parameters is where this method differs from the pre built effects.

The speed and callback parameters serve the same function as in the previous methods. The object property which holds a number of key/value pairs is what it makes this method unique. You pass in each property you want animated along with the final value. For example, suppose you want to animate an element to 90% of its current width, you'd have to do something like:

$("#somelement").animate({width: "90%"}, 350, function(){alert ("The animation has finished running.");});

The above snippet will animate the element to 90% of its width and then alert the user denoting that it has finished.

Note that you aren't limited to dimensions. You can animate a wide array of properties including opacity, margins, padding's, borders, font sizes. The method is also pretty flexible when it comes to units. Pixels, ems, percentages all work. So something as convoluted as the below will work. It just won't look cohesive.

$("#somelement").animate({
width: "90%"
fontSize: "14em",
height: "183px",
opacity: 0.8,
marginTop: "2cm",
marginLeft: "0.3in",
borderBottom: "30mm",
}, 350, function(){alert ("The animation has finished running.");});

When defining a property which consists of more than one word, make a note to define it in camel case. This is in sharp contrast to the usual CSS syntax so make a special note here. It's borderTop, not border-top.

Note: jQuery allows only properties taking numerical values to be animated. This means utilizing only the core, all color related properties are out. Fret not though. With some help from jQuery UI, we'll be animating colors in no time.


Step 4: Tweaking the Effect

If you take a look at the simple effect in the demo, you might have noticed it is a little broken. Hovering on and off the element repeatedly leads to a long queue which inturn leads to the animation repeating itself.

The simplest way to avoid this issue is by using the stop method immediately before beginning the animation. This effectively clears the queue and the animation can proceed as usual. For example, this would be your normal code.

$("#someelement")
  .hover(function() {
    $(this).animate({ top: 20 }, 'fast');
  }, function() {
    $(this).animate({ top: 0 }, 'fast');
  });

Using stop to avoid animation buildups, your new code would look like:

$("#someelement")
  .hover(function() {
    $(this).stop().animate({ top: 20 }, 'fast');
  }, function() {
    $(this).stop().animate({ top: 0 }, 'fast');
  });

Pretty easy, no? But this method does have a small issue. Fast interactions won't lead to buildups but instead to incomplete animations. If you want to completely get rid of this issue, you'll have to turn to a plugin like hoverFlow.


Step 5: Adding a Bit More Realism - Easing

If you'd like to add a little more realism, you'd need more control over the rate at which the animation progresses. This is where easing comes in. Easing essentially controls the acceleration and deceleration of the animation over time.

The default easing method is swing which is built into jQuery. Robert Penner's easing plugin lets you use a number of easing effects. Check out the easing section in the demo to take a look at each easing effect.

There is only caveat when it comes to using a custom easing effect: you can only use it with custom animation effects i.e. with the animate method. Once you have the easing plugin included, making use of a custom easing method is as simple as passing it along as a parameter like so:

$("#somelement").animate({
width: "90%"
height: "183px",
}, 550, "easeInElastic");

Do check out the easing section of the demo to see each method in action. While some of the easing effects may not be suitable for all situations, your animations will certainly look a lot more appealing with the appropriate use of certain easing methods.


Step 6: Kicking it up a Notch - jQuery UI

Upgrading to jQuery UI nets us a number of much needed features. You, in fact, don't need the entire library to make use of the additional features. You just need the core effects file to obtain the functionality. Not the UI core, just the effects core file which weighs in at a relatively miniscule 10 kilobytes.

The important features which the jQuery UI effects library brings to the table are support for animating colors, easing and class transitions.

If you remember, I mentioned previously that with the core jQuery library, you are limited to only animating properties which take numbers. You are rid of this limitation with jQ UI. You can now easily animate an element's background color, its border color and so on. Also, instead of creating a separate function for these extended features, this merely extends the base animate function. This means that if you have the core library included in your file, you can use the ordinary animate method to do all the dirty work for you.

For example, if you'd want to animate an element's border color on hover, your code would look like so:

$(".block").hover(function() {
    $(this).animate({ borderColor: "black" }, 1000);
},function() {
    $(this).animate({ borderColor: "red" }, 500);
});

Class transitions are responsible for animating between classes. With the base library, if you removed and then added a class which changed the appearance of an element, it'd happen instantenously. When you have the UI library on board, you get the option of passing in additional parameters to take care of the speed of the animation, the easing method and a callback. As with the previous feature, this functionality is built on top of the existing jQuery API which eases the transition process.

The final feature which jQuery brings to the table is integrated easing equations. Previously you had to make use of an additional plugin to take care of this but now it comes bundled so you need not worry about it anymore.


Step 7: Building our First Real World Effect

All the above examples were meant to be just demos of the functionality in question. Wouldn't it be nice to actually build something of real world use? That is exactly what we are going to do today. It's not really something radically new or groundbreaking but this demo will let you put what we've learnt today to use in a real world scenario.

Imagine this: You want to display an image and when a user mouse overs it, you display 2 sections inside the image. One shows a heading and the other shows a tiny description of the image. I'm sure you'll find literally a gazillion plugins which do the same but today we are going to build it from scratch. I promise you it's not as hard as it sounds. In fact, it's actually pretty easy and can be very quickly built. Let's get started.


The HTML

First, we need a solid base of markup to build on.

<!DOCTYPE html>
<html lang="en-GB">
<head>
<title>Beginning Animations with jQuery - by Siddharth for NetTuts</title>
<link type="text/css" href="css/style.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jqueryui.js"></script>
<script type="text/javascript" src="js/mojo.js"></script>
</head>
<body>

<div id="container">

<h1>Beginning Animations with jQuery</h1>
<div>by Siddharth for the lovely folks at Net Tuts</div>
<p>A simple real world usage of the animation effects followed by demos for the article's text demonstrating a fix for animation build up and the different easing methods available.</p> 

<div class="bblock">
<h2>A Simple Real World Effect</h2>
<p>When the method is changed, it goes to zero height using the standard jQuery easing and then expands using the specified easing method.</p>

<div class="item">
<div class="title">ThemeForest</div>
<img src="images/tf.jpg" alt="Image" />
<div class="desc">The only place you need for site templates and themes </div>
</div>

<div class="item last">
<div class="title">CodeCanyon</div>
<img src="images/cc.jpg" alt="Image" />
<div class="desc">The premier destination for scripts and code snippets</div>
</div>

</div>

<!-- Rest of the code for the demo -->
</div>
</body>
</html>

For this effect, we'll first need to decide on a structure for each item. Each item is wrapped by a div with a class of item. Inside the div there are 3 elements: the image itself and 2 div elements holding the title and description.

The other parts are rather mundane and self explanatory. We begin by including the jQuery library, the jQuery UI library and our file which holds our custom JS code. Do note that I only needed the effects core part of jQuery UI so I downloaded only that. If you'd like more effects built in, you'll need a custom build. You can download a customized build here.

Here is how our page looks with this phase complete.

Tutorial Image

The CSS

.item {
	position: relative;
	margin: 20px 60px 40px 0;
	overflow: hidden;
}

.item .title, .item .desc {
	background: #000;
	color: #fff;
	position: absolute;
	display: block;
	width: 638px;
	opacity: 0.4; 
}

.item .title {
	top: 0;
	font-size: 16px;
	padding: 12px 10px 25px 0;
	text-align: right;
}

.item .desc {
	bottom: 0;
	font-size: 12px;
	padding: 5px 0 15px 10px;
}

A few things you need to make a note of here. Each item element has its position property set to relative so that elements inside it can be positioned easily. Also, its overflow property is set to hidden so we can hide the title and description outside when they aren't needed.

The title and description have their position property set to absolute so that they can be positioned precisely within the item element. The title has a top value of 0 so its at the top and the description has its bottom value set to 0 so its right at the bottom.

Other than that, the CSS is pretty boilerplate and concerns itself mainly with typography, a little positioning and styling. Nothing too radical.

Here is how our page looks with this phase complete.

Tutorial Image

The jQuery-Enabled JavaScript Magic

$(document).ready(function() 
{
	// Code for other parts of the demo
    
	$(".item").children("div.title").animate({top: -60}, 300);
	$(".item").children("div.desc").animate({bottom: -40}, 300);
    
$(".item").hover(
		function()
		{
			$(this).children("div.title").stop().animate({top: 0}, 700, "easeOutBounce");
			$(this).children("div.desc").stop().animate({bottom: 0}, 700, "easeOutBounce");
		},
		function(){
			$(this).children("div.title").stop().animate({top: -60}, 500);
			$(this).children("div.desc").stop().animate({bottom: -40}, 400);
		}
		);
	
$(".title, .desc").hover(
		function()
		{
			$(this).stop().animate({backgroundColor: "#444"}, 700, "easeOutSine");
		},
		function(){
			$(this).stop().animate({backgroundColor: "#000"}, 700);
		}
		);
});

It may look a little imposing but it's not. Let me explain each part.

The logic of this effect is pretty simple. Since the elements are placed absolutely, we initially place the elements out of the viewport. When the image is hovered over, we just need to move it back to its original position i.e. at the top and bottom of the image.

First, we move the title and description out of view. We do this with JavaScript instead of with CSS for a very specific reason. Even if JS is disabled, it degrades pretty gracefully. The title and description are still overlaid over the image and it looks just like the hover state. If we were to instead use CSS for hiding the title and description and if JS is disabled, they'd be completely hidden and thus useless. I chose to use JS for the dirty work in the interest of progressive enhancement.

We initially bind the our custom code to the hover function of each item element. This lets use make this handler pretty generic and reusable. Adding this functionality to others is as simple as giving it a item class. The first function is for the hover event and the second is for the unhover event.

Within the scope of the function, this refers to the element which triggered the event. We use the animate method to modify the appropriate values. We also use a bit of easing to make it a little more catchy. On mouseout or unhover, we just change the values back to their defaults.

As a little extra, when the containers for the title and description are hovered over, they slowly morph colors, thanks to jQuery UI.

And we are actually done. Didn't take that much time, did it? Not bad for a tiny script which is even more tiny considering how many lines were allocated solely for the curly braces.


Conclusion


And there you have it. How to create animations with jQuery along with a real world example of putting what you've learned to good use. Hopefully, you've found this tutorial interesting, and useful. Feel free to reuse this code elsewhere in your projects and chime in here if you are running into difficulties.

Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!


Write a Plus Tutorial

Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? We're looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you're of the ability, please contact Jeffrey at nettuts@tutsplus.com.

Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.

Write a PLUS tutorial

Advertisement