Using jQuery for Background Image Animations

After reading Dave Shea's article on CSS Sprites using jQuery to produce animation effects, I felt like playing around with things to see what could be done but accomplish it with a simpler HTML structure (no need for adding superfluous tags) and simpler code, too.

Changing the position of the background image felt to be the best approach to creating the type of effect we're looking for (and I'm not the first to think so: see the examples at the end of this article).

jQuery is a great library for this type of task but out of the box, it can't animate background position properly because of the need to animate two values instead of just one (too bad not all browsers implemented the non-standard background-position-x and -y like Internet Explorer). You'll have to use the Background-Position plugin that is linked in the demo (the original plugin is no longer available on the jQuery site). Previous versions didn't support negative or decimal values properly.

The HTML

Nobody likes adding extra HTML to pull off all the fancy stuff and therefore, we're looking at a very simple unordered list:

<ul> <li><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul>

The Basic CSS

For this, I've just floated the navigation and set each of the links to display block with a little padding. Nothing fancy (which is the whole point).

ul { list-style:none; margin:0; padding:0; }

li { float:left; width:100px; margin:0; padding:0; text-align:center; }

li a { display:block; padding:5px 10px; height:100%; color:#FFF; text-decoration:none; border-right:1px solid #FFF; }

li a { background:url(bg.jpg) repeat 0 0; }

li a:hover { background-position:50px 0; }

Notice that a hover state has been declared. Users who visit the page without JavaScript will, at least, still be able to view the final state. I've declared the background on the li a separately to make it stand out, but an initial background position needs to be set along with the background image you want to use for the effect.

The Image

You can pull off different types of effects by creating your image in a particular fashion.

Figure 1: The Swipe

In Figure 1, the before and after states are on the left and right but a simple slant can create an interesting effect.

Figure 2: The Fade

Figure 2 is a little more elaborate. The amount of visible space in the normal and hover states are at the very top and bottom of the image. The large gradient in the middle generates a fade-in/out effect when animated over time. The larger the gradient, the less it'll feel like it's moving in from the bottom and feel more like it's actually fading in and out.

The simplicity of the image allows the file size to be small, as well. More complex animations with more colour depth would require a larger file size. Always strike a balance between the effect and performance.

Check out the demo page to see how these two effects (and a couple others) look in action.

The Script

Finally, the script to put this altogether is really straightforward. The animation needs to run when the user moves their mouse over and out of the navigation.

$('#nav a') .css( {backgroundPosition: "0 0"} ) .mouseover(function(){ $(this).stop().animate( {backgroundPosition:"(0 -250px)"}, {duration:500}) }) .mouseout(function(){ $(this).stop().animate( {backgroundPosition:"(0 0)"}, {duration:500}) })

The elements are captured via the $ function and given a default CSS. This is necessary for both Internet Explorer and Firefox 2, which don't report the default background position. In IE, you can get around the issue using background-position-x and -y but it's easier just to set the initial values in the script.

Then the elements are animated using the mouseover and mouseout events.

The key thing to note is that any animation is stopped before attempting to animate again. This avoids animations queuing up from repeatedly moving the mouse in and out of the element.

jQuery also has a hover method which can be used instead of separately using the mouseover and mouseout methods. The reason I didn't was because I like the clarity that is provided by explicitly declaring them. The hover method takes two parameters: the function to run when over and the function to run when out.

The Demo

On the demo page, I've created four separate animations. Just hop to the source to see how it was all put together.

Other jQuery Examples

As mentioned, I'm certainly not the first to come up with this idea. Check out these other resources for more jQuery navigation animation exploration.