Snook.ca

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:

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.

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.

It's a very cool effect but I tried to desactivate JavaScript and it wouldn't do anything. I mean, there's no alternative. Is it possible to have that cool JQuery effect, and, IF there's no JS, have the "simple" CSS effect ?

I also like that you get a 'bonus' effect if you roll in and out of the button very quickly on the animated image examples, since the image simply tends to animate toward the final state, rather than jerking to the beginning of the mouseout state.

Thanks Snook! I was a bit aggravated with Dave's demo and all the extra classes he had in the code. I also did not like the fact that he used a hidden div to overlay over the menu items. Snook 1, Shea 0.

@James: indeed it could. However, interestingly, the use of image + background-position plugin may end up smaller than using the color-animation plugin. But always nice to have options. Thanks for pointing it out.

I too like this better than Dave's version which I had started incorporating into a new design buit will now switch, however this version doesn't have the "active" state setup. I guess that would be easy to do... but I'm lazy and would rather copy/paste.

Great writeup Jonathan! As I was reading Dave's ALA article I kept thinking the same thing...why wouldn't you do it with an animated background? I'll definitely be using this type of effect on future projects.

While it isn't nav/sprites related, I recently used JQuery and the background-position plugin on a client project. Thought I might as well post up a quick demo here in case anyone is trying to do something similar.Background Image Animation Demo

Looks nice, but in the end its just the continuation of manipulations of the position of background-images with CSS (like with image-rollovers). Only the creativity sets the limits of animating CSS properties with JS.

Just an idea: Maybe its more helpful to a greater audience, if such things are described in a more general way and more as an impulse to get started. There are still many other JS frameworks out there and in use.

This is great. I have seen a few other ones in recent weeks, and used a hybrid myself, but I like this approach. One accessibility enhancement suggestion, however: use the focus and blur events to run the same code as mouseover and mouseout events, for keyboard accessibility. I just tried it locally and it worked quite nicely with keyboard access too.

this literally could not have come at a better time! I've been fooling around with a menu using the sprite technique and the client really wanted flash. I just didn't see the need for the menu to be flash. This plug-in will work perfectly!

Dave: that's why I presented a no script option at the top of the page. The other examples demonstrated the script. It was an exercise for the user to put it all together. :) (and thanks for doing so...)

I wrote a similar tutorial a while ago that demonstrated how can you fade between two images to create a similar effect. I took a similar approach to yours. For those interested, it can be found at http://swedishfika.com/2008/03/04/creating-a-fading-header/

Great job.
Simple and at the same time pretty usage of jQuery. I wrote a russian translation of this article at http://habrahabr.ru/blogs/webdev/40801/ and it achieved a lot of positive feedback. Thanks a lot.

Excellent! Now I've got a bigger challenge for you: How about changing the opacity of the background image, or at least simulating such an effect, without adding to the complexity of the XHTML markup? I've already spent some time working with this but alas without success.

Something to be aware of is jQuery's hover function actually uses the mouseenter/mouseleave events (either the proprietary IE version or an emulation of them in other browsers) whose behavior is somewhat distinct from mouseover/mouseout.

Well I copied everything verbatim from the test page (images, js, the whole bit) to play with in on our test server, but it doesn't work. At all. Very strange. The "wave" animation gets stuck in the middle, and the rest get stuck too. Oh well, off to find another slick jQuery navigation trick. :(

this script absolutely does not work. i would not waste your time. the author has obviously used additional scripting to get it to work. This tutorial was written for search engine ranking and nothing else. Free stuff gets hits. :(

**TUTORIAL ADDED TO JUNK TUT DATABASE**
This tutorial has been added to the Junk Tut Database as part of the Junk Tutorial Project to be launched soon to help unsuspecting web users avoid time-wasting tutorials such as this.

@derrick, just because you aren't competent enough to get this to work doesn't mean its broken. It works just fine for me. Please take your arrogant and threatening comments somewhere else. I'm sure you will be added to the akismet spam DB if snook uses it, at least I would.

@derrick: no, it was completely solved. I just double-checked the test page you had sent me via email and the one animation that doesn't "work" is because you're animating along the X axis when the image only changes along the Y axis.

You are probably very busy but I want to add the effect : When you click on a header link, the background stay in the second color (active tab). In wordpress there is a "current_page_item" we must add in CSS to do so but I don't success...

Very nice. actually the background animation can have some variations. Simply adding a png format image serving as a text mask can create a very nice effect. I have made a page according to your inspiration. see my site for demonstration

Jonathan, thank you for the quick reply. Follow-up article makes sense but I was hoping you would explain how to do it using 'onclick', 'addclass' type of route or add conditions at the beginning. The reason for this (for me) would be to 'include' menu as part of header through php. Well maybe when you have time you could expand this tut more.

This is a wonderful snippet of code. It took me a little bit of a moment to figure it out (due to my lack of solid CSS and ASP.NET masterpage knowledge), but it was fairly easy to follow. Any ideas on how to get rounded edges for this concept, without any IE/other browser hacks?

Jonathan,
thank you for funtastic plugin! I can see that your example works just fine in IE7 but mine shows only hover state. Do you have any idea why? Thanks again.

Sorry, comments are closed for this post. If you have any further questions or
comments, feel free to send them to me directly.

Hi. My name is Jonathan Snook and this is my site. I write about what interests me, which is usually web design, development, and technology. I'm also in the middle of a food adventure.
I wrote SMACSS. I tweet. Want to learn more?