I recently stumbled upon Dragon Interactive (dragoninteractive.com). It’s a pretty well designed site. However, the pièce de résistance is their rather cool animated menu. Now… had this been designed in Adobe Flash, I wouldn’t had paid much attention. A closer inspection revealed that the menu is plain XHTML, CSS and Javascript. Today, I’m going to show you how to create an animated menu (very similar to Dragon Interactive’s menu).
Designing The Sprite
To begin with, you will need to build your design in Adobe Photoshop - or some other illustration program. You will need to design a sprite. I also quickly designed a repeating background image (just to make things look pretty):
![]()
The XHTML Markup
Here is the XHTML markup that is used in the demo:
<ul id="menu"> <li><a href="#" class="home"><span></span></a></li> <li><a href="#" class="portfolio"><span></span></a></li> </ul>
As you can see, an unordered list is used to structure the menu. In this tutorial, I’m only going to create 2 links. You can add as many links as you desire. Notice that each link is given a unique class. We will need to work with each class individually when we write the CSS.
The CSS
For the demo, I assigned the repeating image as a background image for the <ul> element. I also set the height and width:
ul#menu { width:80%; height:102px; background:url(bg.png) repeat-x; list-style:none; margin:0; padding:0; padding-top:20px; padding-left:20%; }
Notice that in the above CSS, “list-style:none;” is used to prevent styling the list using the default bullet point format. The rest is pretty self-explanatory. We will now need to float each <li> element so that the list elements are displayed horizontally rather than vertically:
ul#menu li { float:left; }
Now we get to the good stuff! We’re going to need to add the sprite as a background image to each link in the menu. However, we only want to display a section of the sprite for each link. We do this by restraining the link to some specified dimensions and then positioning the background image accordingly. Let’s look at the following sprite:
![]()
Each column represents a different link. In this case, we only have 2 columns since we only want 2 links. The bottom row defines how the link will look when you hover over it with your mouse cursor. Now, say we define the link to have a height of 81px and a width of 159px. If the background image is then positioned to the top left, we see that only the “Home” button is displayed:

This is because the “Home” button was designed such that it has a height of 81px and a width of 159px. As the background is positioned to the top left, this is the only part of the image that will fit inside the link - which is obviously when we want! So, how do we write this using CSS? Well… first you will need to recognise that in most cases, we will want more than a single link (in this case - 2 links). Hence, it is easier if we write some common CSS for all the links (i.e. CSS that may be inherited by each and every link in the menu). We can always add to (or overwrite) these common CSS attributes by later writing CSS for each specific class assigned to the link (see XHTML markup). Here is the common CSS that is used in the demo:
ul#menu li a { background:url(sprite.png) no-repeat scroll top left; display:block; height:81px; position:relative; }
In the above code, we position the background image to the top left. This is fine for the “Home” link. However, for the “Portfolio” link, we will need to overwrite the background position attribute for concerning class (see XHTML markup). Please also note that we define the height here since all the links will have the same height. As links by default are displayed inline, we must use “display:block” to specify the height of the link. Finally, we must position the link relatively. It will become apparent why we need to do this later.
We will now need to write some CSS for each individual link. We do this by specifying the class (see XHTML markup). This tutorial deals with just 2 links. The “Home” link has the class: “home”. The “Portfolio” link has the class: “portfolio”. We can hence define CSS attributes for each individual link as follows:
ul#menu li a.home { width:159px; } ul#menu li a.portfolio { width:157px; background-position:-159px 0px; }
Notice that it is here where we specify the width of the links (since each link may have a different width according to the design). It is also here that we overwrite the background position attribute if needed. We do not need to do this for the “Home” link since the common class already has this defined as “top left”.
We will want to position the sprite differently for the “Portfolio” link. Since the “Home” link is 159px wide, we will need to shift the background position 159px to the left in order to focus on the “Portfolio” area. We do this by writing “background-position:-159px 0px;”. This tells the browser to shift the background 159 pixels to the left and 0 pixels down. You can learn more about positioning background images using CSS over at SitePoint.

We now need to create the “hover” state. This is how the link will appear when you hover over it with your mouse cursor. The animation will blend between the 2 states. To create the hover state, we’re going to use a <span> tag. We’ll then use CSS to have that span tag completely fill the link (so that it is exactly the same size as the link). We’ll also need to shift the background image down for the span in order to display the “hover” area of the sprite. As before, we’ll use some common CSS:
ul#menu li a span { background:url(sprite.png) no-repeat scroll bottom left; display:block; position:absolute; top:0; left:0; height:100%; width:100%; z-index:100; }
Note that we again use “display:block;” since, by default, the <span> tag is displayed inline. Now that the <span> is displayed as a block, we can define the height and width to 100% - completely filling the link (so that the span and link are exactly the same size). Also notice that we position the <span> absolutely inside the relatively positioned link. Positioning the <span> in this way allows us to define a z-index. The assigning a high z-index ensures that the span’s background is displayed above the link’s background. All that we are left to do is position the background for the <span> tags (contained within the links):
ul#menu li a.home span { background-position:0px -81px; } ul#menu li a.portfolio span { background-position:-159px -81px; }
Notice that we shift the background down by 81 pixels for each span tag (since the height of the “Home” link is 81px). This causes the “hover” state to be displayed within each span tag. As before, we also shift the background left by 159px for the “Portfolio” link.
Using jQuery For The Animation
The animation is really quite simple. We’ll use jQuery to animate the opacity of the <span> tag. Remember that the <span> tag displays the “hover” state of the image. Hence, when the <span> is visible, the link takes the “hover” appearance. We’ll need the “hover” state to be invisible when the page loads. We can do this by setting the opacity of the <span> tag to “0″:
$(function() { // set opacity to nill on page load $("ul#menu span").css("opacity","0"); // the rest of the code will go here });
Placing the code inside of “$(function() { … });” tells the browser to execute the code when the document has loaded. The code that we’ll use to do the animation is as follows:
// on mouse over $("ul#menu span").hover(function () { // animate opacity to full $(this).stop().animate({ opacity: 1 }, 'slow'); }, // on mouse out function () { // animate opacity to nill $(this).stop().animate({ opacity: 0 }, 'slow'); });
Hence the entire Javascript used is as follows:
<!-- Include jQuery Library --> <script src="jquery-1.2.2.pack.js" type="text/javascript"></script> <!-- Let's do the animation --> <script type="text/javascript"> $(function() { // set opacity to nill on page load $("ul#menu span").css("opacity","0"); // on mouse over $("ul#menu span").hover(function () { // animate opacity to full $(this).stop().animate({ opacity: 1 }, "slow"); }, // on mouse out function () { // animate opacity to nill $(this).stop().animate({ opacity: 0 }, "slow"); }); }); </script>
Notice that we first include the jQuery library. You can learn more about jQuery animations by reading up on the documentation. One final addition to the CSS is required to ensure that the mouse cursor is display as a pointer when hovering over the <span> tag:
ul#menu li a span:hover { cursor:pointer; }
The full source code can be accessed via the demonstration page. I should just add that whilst this code seems to work well with FireFox and IE7, IE6 might (and probably will) be a different story.

July 3, 2008
Quote
Wow! I’m “googling” for “jquery menus” and I’ve found your site with this tutorial! And I don’t understand why it doesn’t have any comment!
It’s FANTASTIC!
Thank you so much, I’ll add shopdev.co.uk to my favourites now.
David Carreira
July 3, 2008
Quote
Many thanks! I’ve used the same principal as outlined in the tutorial for the logo at the top of this page. Again… thanks for the feedback!
July 15, 2008
Quote
NICE tutorial mang.
July 19, 2008
Quote
Very nice effect! Also very smart to stop() the animation on a change.
July 25, 2008
Quote
Thank you so much for this mate.
Great tutorial!
And I’ve added to it slightly. Instead of having the text contained within the image, I wanted it contained in the “a” tag for SEO purposes. So my link now looks like:
Also, I set up a sprite with multiple colours.
View an example here:
http://www.mmr.com.au/resource.....matedMenu/
July 25, 2008
Quote
sorry the tag didn’t work correctly with previous post:
July 25, 2008
Quote
Looks awesome! I edited your post as it looks like you forgot to wrap the code in “pre” tags. Thanks for the comment!
July 30, 2008
Quote
Man, this is amazingly nice.
Many thanks for the tutorial. (in fact I was just looking for a solution on how to stop the animation if you hover/out your mouse quickly. I found it also) !
August 17, 2008
Quote
this is exactly what i was looking for! anyone come up with an IE fix for it?
August 20, 2008
Quote
thank you!
i’ve try to find this effect so long
August 26, 2008
Quote
You’re very welcome guys!
@ Trisha, you could probably get the script to fall-back (without the fading transition). I don’t think that there’s a clever trick to get this working in IE6.
Just a note : IE7, Transparent PNGs & jQuery Animations do not play nicely. Avoid using transparent PNGs.
August 27, 2008
Quote
I have a question. Why are there scanlines on the sprites? Those do not appear in the example.
August 28, 2008
Quote
Hi Ethan!
If you’re talking about the images in the tutorial, the scanlines are meant to signify parts of the sprite not visible to the end user.
August 31, 2008
Quote
[…] Animated Menus Using jQuery (tags: CSS jquery navigation) […]
September 1, 2008
Quote
Hello - nice work! I took a look and implemented something very similar on my children’s party supplies site. With some jigging around I managed to use the same ’sprite’ for both the background, the foreground and the images that sits on top of it.
September 2, 2008
Quote
[…] ShopDev shows reverse-engineers the the interactive menus used on Dragon Interactive and shows how to were pull it off using JQuery. […]
September 4, 2008
Quote
very concise, and thorough instruction -thanks