Animated Navigation with CSS & jQuery
Blog » CSS/XHTML » Animated Navigation with CSS & jQueryAnimated Navigation with CSS & jQuery
As I was checking out some flash sites for inspiration, I ran across a couple websites that had some nice navigation effects. I’m not a huge fan of wildly animated navs, but these had simple and elegant roll over effects that I liked. I decided to imitate the effect with CSS and jQuery, and would like to share this technique today.
Step 1. Wireframe – HTML
This part is very simple. Your typical unordered list with links.
<ul id="topnav">
<li><a href="#">Home</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Portfolio</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
Step 2. Styling – CSS
Only thing special about the below properties will be that each list item has an overflow of hidden to imitate the masking technique. Check out the image below to see what I mean.

Notice there were no duplicate <span> tags in the markup in step 1. We will be adding that later with a few lines of jQuery.
ul#topnav {
margin: 0;
padding: 0;
list-style: none;
float: left;
font-size: 1.1em;
}
ul#topnav li{
margin: 0;
padding: 0;
overflow: hidden; /*--Important - Masking out the hover state by default--*/
float: left;
height:40px;
}
ul#topnav a, ul#topnav span { /*--The <a> and <span> share the same properties since the <span> will be a duplicate of the <a> tag--*/
padding: 10px 20px;
float: left;
text-decoration: none;
color: #fff;
background: url(a_bg.gif) repeat-x;
text-transform: uppercase;
clear: both;
width: 100%;
height: 20px;
line-height: 20px; /*--Vertical alignment of text--*/
}
ul#topnav a{ /*--This is basically the hover state of navigation--*/
color: #555;
background-position: left bottom;
}
ul#topnav span{ /*--Default state of navigation--*/
background-position: left top;
}
Step 3. Animation – jQuery
For those who are not familiar with jQuery, do check out their site first and get an overview of how it works. I’ve shared a few tricks that I have picked up along the way, you can check those out as well.
Initial Step – Call the jQuery file
You can choose to download the file from the jQuery site, or you can use this one hosted on Google.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
As you can see below, we are duplicating the span tags, then animating them -40px to the top to shift the navigation.

The following script contains comments explaining which jQuery actions are being performed.
$(document).ready(function() { $("#topnav li").prepend("<span></span>"); //Throws an empty span tag right before the a tag $("#topnav li").each(function() { //For each list item... var linkText = $(this).find("a").html(); //Find the text inside of the <a> tag $(this).find("span").show().html(linkText); //Add the text in the <span> tag }); $("#topnav li").hover(function() { //On hover... $(this).find("span").stop().animate({ marginTop: "-40" //Find the <span> tag and move it up 40 pixels }, 250); } , function() { //On hover out... $(this).find("span").stop().animate({ marginTop: "0" //Move the <span> back to its original state (0px) }, 250); }); });
Conclusion
Fancy but a very simple technique! The good thing about this technique is that it degrades gracefully and is still accessible even if js is turned off. If you have any comments, suggestions, or questions please feel free to let me know.
Other Fancy Navigations
- Using jQuery for Background Image Animations
- Create a Cool Animated Navigation with CSS and jQuery
- Animated navigation items using jQuery
- How To Create A ‘Mootools Homepage’ Inspired Navigation Effect Using jQuery
Similar Posts:
Tags: jQuery, navigation
This entry was posted on Tuesday, July 28th, 2009 at 12:49 am and is filed under CSS/XHTML. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.







very nice!
Thank you, cool navigation. Your Wordpress theme is also cool.
Hi guy, is it possible to do vertically ? Thanks to you and long life to SOhTanaka !
Wow, thanks for sharing; I see the contact button which is not aligned;: it floats under the home button. (FF 3.5.1 on a mac)
Claudio, thanks! I dont think my container was wide enough~
Dude – i do like your site a lot. One problem with this example however is that is JavaScript is turned off, none of the links seem to work because they are all hidden
Hey great navbar! Just to let you know the second navbar(The No background one) does not look so good in IE7, actually it does not work at all in IE7.
@ Matt, they do work w/out js. Have you tried to disable js? Maybe you thought it didn’t work because I just had “#” in the links. I added some real links so its not confusing
@FireDart thanks for catching that X-p updated this now, was one of those late night blog posts. thanks for catching!
Great advice and examples as per usual.
Can the menu’s be created without the text as part of the image and the text added as part of the page code? With multi-lingual websites it just looks plain daft.
Thanks again.
Hey Barton, I’m not sure if I’m misunderstanding you but the nav text is actual pixel text rendered by the browser. Not a graphic. Is that what you meant?
i like this alot.
I was wondering how would I go about adding a “current” state options to the mix.
thx
Awesome. I am going to use this for my site
thanks for sharing Soh.
Very nice navigation
I like this alot, Looks very simple. Was trying to do something like this with jQuery but instead of animating position, is it possible to animate visibility/opacity
thanx
Thanks a lot Soh, i followed the steps that you had mentioned here, but i am unable to have it render properly in Safari 4.0.2. When it initially shows up in Safari, only a part of the Red background is coming, covering only the first two letters. But after a mouse-over event it is working properly. But i checked in Firefox, and it is working properly. Any ideas?
Great tut. Keep up the great work. You are one of the few that illustrate in detail your methods – great for js and css beginners such as myself.
Very nice Tutorial! If you are interested in more jQuery, watch the following article: “jQuery – The easy way to navigate”!
@soh: yeah man, i disabled JS (using the developer toolbar in FF 3.0.12) I can see that you’ve changed the links. I just can’t see the hyperlinks when JS is turned off unless I disable CSS also.
regardless of that – I still think it’s nice
Soh, my mistake, 100% spot using text rather than images.
BRILLIANT, keep’em coming.
Barton
Very nice but if JavaScript is turned off, no hover and no focus on links.
Echoing jem’s comment–how would we go about adding a “current” state to the CSS?
Thanks a lot for this beautiful post
Moo?
Here: http://paste.mootools.net/f344a2aa
@Ray do you have a sample link to what you have so far?
@Jonathan, if you still want the CSS hover effect just in case js is disabled, you can add the hover properties in your css, and have jquery override it once it loads~ So this way ppl with js will see the enhanced nav, and ppl without can still see the default css version~
@those who asked about active state, you can check out a demo version here.
http://www.sohtanaka.com/web-design/examples/fancy-navigation/home.htm
I added comments in the source code, just make sure your list item class matches your body ID exactly
hi,Soh
thank you very very much. i luv this nav.
Soh, Here is the link to the test page : http://pics.heliohost.org/Testing/Navigation.html .
Thanks.
I have this bug if there is a space in the “a” like “my work” it dont stay inline
Like:
MY
WORK
After the hover action no prob….
Any idea..?
BTW thank for the tuts you are a great teacher…
I had this in my css it fix the thing…
ul#topnav a, ul#topnav span{
width:100%;}
thanks again
Ah I see the issue Ray, it was my fault. As Dave mentioned you need a width of 100% on the span/a.
Thanks Dave for pointing that out
One way to do this without having to use images for the nav text is to animate the background image only and have your menu li items on top, like this:
http://snook.ca/archives/javascript/jquery-bg-image-animations/
@ adam; the examples from the link above also include a nice fade between colours
I’m still designing my blog. I liked this animated menu. I think I’ll use it.
I’d ad this to my CSS to prevent the cursor from flickering between default and pointer:
ul#topnav li {
cursor: pointer;
}
Thanks Soh
Hi, awesome tutorial. I’ve tried to use a MySQL database with it, so I can update the text and links used in the menu.
It almost works, just a question if you know the answer:
I only get the first button (Home button) working, the rest is not showing ?
Here’s my modified code for the Wireframe/HTML:
query($sql) or die(mysqli_error());
?>
fetch_assoc());
?>
Oops, here the rest of the code:
<body>
<?php
$file = include($_SERVER['DOCUMENT_ROOT'].'/mysite/includes/connection.inc.php');
if (file_exists($file) && is_readable($file)) {
include($file);
}
$conn = dbConnect('admin');
$sql = 'SELECT id, title, url,
DATE_FORMAT(created, "%a, %b %D, %y %H:%i") AS created
FROM menu_text ORDER BY id ASC';
$result = $conn->query($sql) or die(mysqli_error());
?>
<ul id="topnav">
<li>
<?php
do {
echo $row['url']; echo $row['title'] ;
}
while ($row = $result->fetch_assoc());
?></li>
</ul>
</body>
</html>
@Ed, this navigation is text-based, no images needed
@Corey, thanks for the suggestion
@Jake I’m sorry but I don’t think I can be of assistance on this one
Thanks for sharing this Soh.
woo…………… very nice
Nice tutorial
extremelly cool
Sorry if someone already mentioned this, but, for those saying you are unable to click the links with javascript turned off, and are using the firefox developer toolbar, refresh the page after you disable the javascript and you can see that it still works
This is a lovely menu and is exactly the type of thing I was looking to put together.
I there
Just an other issue…
width: 100%; worked great until i test in IE6 (no wonder)
It mess up with the float left and doesn’t stay inline…
do somebody have a clue..?
Thank you to making the animated menu. I liked this animated menu. I think I’ll use it.
If I preview this script in IE7 it will show up in a vertical wide position
Very cool use of jQuery! I love your tutorials!
Adaptation for mootools:
window.addEvent(”domready”, function(){
var li_a = $$(”#topnav li”);
li_a.each(function(li){
var span = new Element(’span’);
span.inject(li, ‘top’);
var linkText = $(li).getElement(”a”).get(”html”);
$(li).getElement(”span”).set(”html”, linkText);
li.addEvent(”mouseenter”, function(e){
new Event(e).stop();
var fx = new Fx.Morph($(this).getElement(”span”));
fx.start({
“margin-top”: [0, -40]
});
});
li.addEvent(”mouseleave”, function(e){
new Event(e).stop();
var fx = new Fx.Morph($(this).getElement(”span”));
fx.start({
“margin-top”: [-40, 0]
});
});
});
})
just curious if this can be done vertically?
I was playing with it but couldn’t get it to go.
was pretty excited until i looked in IE7 .. as Patirck mentions .. it is displaying vertically … FF is fine.
it is very cool and i hate to bag on something free, but is there a fix ?
putzing with some of the css found in other site’s examples, I found that removing this line fixes the issue of IE 7 displaying the list vertically …
ul#topnav a, ul#topnav span {
width: 100%;
cool stuff !
@ Gymlady + Patrick, thats strange. Seems like its working for me…
IE7 Screen Shot

Any chance to get this code w3 valid?
I get error on:
$(document).ready(function() {
$(”#topnav li”).prepend(”"); //Throws an empty span tag right before the a tag
$(”#topnav li”).each(function() { //For each list item…
var linkText = $(this).find(”a”).html(); //Find the text inside of the a tag
$(this).find(”span”).show().html(linkText); //Add the text in the span tag
});
$(”#topnav li”).hover(function() { //On hover…
$(this).find(”span”).stop().animate({
marginTop: “-40″ //Find the span tag and move it up 40 pixels
}, 250);
} , function() { //On hover out…
$(this).find(”span”).stop().animate({
marginTop: “0″ //Move the span back to its original state (0px)
}, 250);
});
});
gives me this error:
Line 31, Column 32: document type does not allow element “span” here
$(”#topnav li”).prepend(”"); //Throws an empty span tag right befo
✉
The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements — such as a “style” element in the “body” section instead of inside “head” — or two elements that overlap (which is not allowed).
One common cause for this error is the use of XHTML syntax in HTML documents. Due to HTML’s rules of implicitly closed elements, this error can create cascading effects. For instance, using XHTML’s “self-closing” tags for “meta” and “link” in the “head” section of a HTML document may cause the parser to infer the end of the “head” section and the beginning of the “body” section (where “link” and “meta” are not allowed; hence the reported error).
DROPDOWN MENU: I love your site and the fancy nav. I would like to add a dropdown menu, but the tags continue to work on the ul#topnav li. Is it possible to hover and get the fancy nav and a dropdown menu with plain text? I have worked on this for 2 days. Otherwise everything works great. Thank you so much.
Hey Soh, you have a bug, when you press the tab key, in the keyboard the menu dissapear, and never come back. Regards, From Mexico.
here is the post .. still cannot in IE7
Thanks for sharing this fantastic technique, works like a charm and only takes 5 minutes to implement!
i salute you boss. cool and fundu…
oooooo….
great…
i love it….
@Anders I have the same problem.
The code w3 is not valid.
$(”#topnav li”).prepend(”"); //Throws an empty span tag right before the a tag
here, the code :
$("#topnav li").prepend("<span></span>"); //Throws an empty span tag right before the a tag
If the user clicks the link quickly, they may click the tag before it’s finished animating, meaning the link goes nowhere. I have proposed a small addition to the script:
If the user clicks the link quickly, they may click the <span> tag before it's finished animating, meaning the link goes nowhere. I have proposed a small addition to the script:
$("#menu li").each(function() { //For each list item…
var linkText = $(this).find("a span").html(); //Find the text inside of the <a> tag
var linkHref = $(this).find("a").attr('href'); //Find the href inside of the <a> tag
$(this).find("span.off").show().html(linkText)
.click(function(){ window.location = linkHref; });; //Add the text in the <span> tag
});
Cool !
Great tutorial but what would I do if I wanted to center the navigation?
great web site design!!, very clean!
Love your posts. Your website is amazing. Keep writing
CG
Hey quick question. How would I go about controlling the horozontal spacing?
@ibkiwi you can add horizontal spacing by increasing the padding size on the ul#topnav a, ul#topnav span ~
Drop Down Menu!
Thanks a lot for this tutorial Soh, you rock!
But Like some other guys here said, could you explain how to keep the effect and add drop down menu? Ive been trying 3 days now and cant make it work properly. please
Thanks
very nice
very impressive.
any chance to use current state; when opened a page from menu it should indicate what link is active?
Thank you for creating this tutorial site! Thumbs up!
Hello Soh and thank you a lot for the tutorial.
I’m a novice and after a reading I don’t understand how is possible to integrate in a Wordpress theme.
Could you give me a direction by a list of files to modify ?
Thanks in advance,
Massimo
Hi
I’d love to see a dropdown menu example using this menu too…
Thanks a lot
Hi, thanks for nice tutorial.
I have the same problem as Tim (August, 31st message) – if you click quickly link doesn’t work. But his proposal doesn’t work as I am a novice at jQuery. If it is possible, could you please publish here the complete solution how to avoid the problem?
Thank you.
I would like to say one thing, is this menu IE6 compatible, i tried to use it in one web design but failed to get it right in IE6, animation works fine but all the buttons go in vertical direction spanning through whole page……..can anybody give me solution to this problem.
how to set “current” menu image?
The menu looks great, and works great too. My only issue is that when the is put inside a table cell, i get display issues on IE7 and IE8. There is a large space above the menu.
Everything is beautiful in other browsers. My question is this…. Is this just a issue, and could i fix it using divs? Or is there an IE hack for it?
Hi saw, i love this menu, i’m trying to use it on a site i’m doing for a client.
This site is just one page with tabs, i want to use this menu to toggle the tabs. Is there a way i can set active state (as the hover state) on a clicked link. This is so the viewer can see which tab they are on.
Please advise.
this is sooo cool…! thanks for the tips. hope you could post more of this useful tutorial!
There’s an issue where more than one word can’t be used within a list-item (see below):
<a href="http://rickymuldrew.com/cash-cow/">here</a>
Any ideas what the problem could be?
@Richard – It seems there is a problem with the width of the ul#nav a.
Start a new line (so it does not affect the span) and add
ul#nav a {width: 100%;}
Someone mentioned there was an IE6 bug with that (but i think its putting 100% on the span that was the issue), so be sure to check that out before publishing to live
Let me know how that goes.
Very Nice ..
Perfect article, thanx
I check with http://validator.w3.org and it shows some error(Invalid)
Greetings. Thanks for a lesson.
How it is possible to realise animation from top to down (instead of from below upwards)?
I found that specifying ‘ul#topnav a, ul#topnav span {width: auto;}’ in my ie6 stylesheet helped. Wish that ie6 would just disappear already.
Hi there.
I’ve been trying to get your menu bar working on my site, it’s perfect, apart from an error I get when I include my IP.Shoutbox javascript library, and it stops working.
Here is the shoutbox.js file that is conflicting.
http://www.diadem5.com/forums/jscripts/shoutbox/shoutbox.js
Could you take a look?
Thank you so much in advance!
Awesome! Very clear and easy to follow and beautiful results. I LOVE jquery.
Your theme is very elegant.
@Jeff
you may have two different libraries conflicting. You should put jquery into no conflict mode. I think you have to change the “$” to “jquery” or “j$” in Soh’s script.
Here’s more info:
http://digwp.com/2009/06/including-jquery-in-wordpress-the-right-way/
Hi All
What about “Current” status apply on menu???????????????????
This is really very good… Thanks
nice nav bar…. why isn’t working in blogger?
somebody can help me
Soh, first off I love your site and all the tutorials you post… Its in my list of 4 web design sites I visit everyday.
I am having a problem getting this to work with ie6. I tried some of the solutions above but none seen to be working. The link to my site is below.
http://vismarkgroup.com/dev/vision/
Any help you can lend would be greatly appreciated.
@Kiran and other who wish current status on menu:
jquery
$("ul#topnav li a").click(function() {
$("ul#topnav li").removeClass("activeButton");
$(this).parent().addClass("activeButton");
});
and css
ul#topnav li.activeButton span { color: #000; background-position: left bottom;}
Great job and thanks for all of your helpful lessons. Any idea how to alter this to be like the Nav on http://www.colourlovers.com/?
Oh I do like this menu! Must find a site to use it one. I’ve seen this sort of thing before, but those examples used large images that held the entire menu text. This is a lot better.
This is Soh Amazing!
Exactly what I needed! Thank you
//This is very nice. Thanks for sharing
Awesome tutorial and great explanation of it. I was wondering if was possible to create an active to the navigation.
Thanks Soh! I got it to work vertically…remove the code that adds the span and manually insert the span after the anchor tag. then revers the marginTop in the jQuery code and add a negative top margin in the CSS on the span…ta da
nice menu but dosnt work in ie 6
awesome… thanks
I Love it! Will use this very soon on my home page.
Those wishing to validate,
Place your javascript in a new doc:
$(document).ready(function() {
$(”#topnav li”).prepend(”"); //Throws an empty span tag right before the a tag
$(”#topnav li”).each(function() { //For each list item…
var linkText = $(this).find(”a”).html(); //Find the text inside of the tag
$(this).find(”span”).show().html(linkText); //Add the text in the tag
});
$(”#topnav li”).hover(function() { //On hover…
$(this).find(”span”).stop().animate({
marginTop: “-40″ //Find the tag and move it up 40 pixels
}, 250);
} , function() { //On hover out…
$(this).find(”span”).stop().animate({
marginTop: “0″ //Move the back to its original state (0px)
}, 250);
});
});
——————————————————
and save it as (or whatever you want) fancy.js
Then call it in your html after you call jquery.js:
————————————–
—————————————-
save and revalidate!
-Daniel
Hi, thanks for making this tutorial.. I really like it, and I’m using it on a site I’m making. But there is a problem.. when I reload the page then it does something and it displays the bottom half of the graphic. if you need to see it then go here: http://www.aninspirededucation.com/newsite/menu
wait.. now its working mostly.. only sometimes it does that, but I have no idea why.. it only does it mostly when I’m viewing it locally, could this be the problem??
Man I love your work ;D