Animated Navigation with CSS & jQuery

Blog » CSS/XHTML » Animated Navigation with CSS & jQuery

Animated Navigation with CSS & jQuery

PrintJuly 28th, 2009

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.

jQuery Navigation - CSS

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.

jQuery Navigation - CSS

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.

jQuery Navigation - CSS

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);
	});

});

jQuery Navigation - CSS

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

Did You Enjoy This Post?

subscribeSubscribe via RSS ,by email, or by twitter to get all upcoming
tutorials and articles delivered straight to you.

Bookmark or Share this Post!

  • Digg
  • del.icio.us
  • StumbleUpon
  • Technorati
  • Twitter
  • E-mail this story to a friend!

Tags: ,

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.

105 Responses to “Animated Navigation with CSS & jQuery”

  1. art

    very nice!

  2. andreeib

    Thank you, cool navigation. Your Wordpress theme is also cool.

  3. Zeb

    Hi guy, is it possible to do vertically ? Thanks to you and long life to SOhTanaka !

  4. claudio

    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)

  5. Soh

    Claudio, thanks! I dont think my container was wide enough~

  6. Matt

    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 :(

  7. FireDart

    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.

  8. Soh

    @ 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!

  9. Barton

    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.

  10. Soh

    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?

  11. jem

    i like this alot.

    I was wondering how would I go about adding a “current” state options to the mix.

    thx

  12. Sam

    Awesome. I am going to use this for my site

  13. massimo

    thanks for sharing Soh.

  14. JH

    Very nice navigation

  15. adam

    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

  16. Ray

    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?

  17. Tim

    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.

  18. Webstandard-Team

    Very nice Tutorial! If you are interested in more jQuery, watch the following article: “jQuery – The easy way to navigate”!

  19. Matt

    @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 :)

  20. Barton

    Soh, my mistake, 100% spot using text rather than images.

    BRILLIANT, keep’em coming.

    Barton

  21. Jonathan

    Very nice but if JavaScript is turned off, no hover and no focus on links.

  22. ruby

    Echoing jem’s comment–how would we go about adding a “current” state to the CSS?

  23. Alfredo

    Thanks a lot for this beautiful post

  24. Fabian
  25. Soh

    @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 :-)

  26. chirag

    hi,Soh

    thank you very very much. i luv this nav.

  27. Ray

    Soh, Here is the link to the test page : http://pics.heliohost.org/Testing/Navigation.html .

    Thanks.

  28. DAVE

    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…

  29. DAVE

    I had this in my css it fix the thing…

    ul#topnav a, ul#topnav span{
    width:100%;}

    thanks again

  30. Soh

    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 :-)

  31. Ed

    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

  32. Leila

    I’m still designing my blog. I liked this animated menu. I think I’ll use it.

  33. Corey Worrell

    I’d ad this to my CSS to prevent the cursor from flickering between default and pointer:

    ul#topnav li {
    cursor: pointer;
    }

  34. Ray

    Thanks Soh :-)

  35. Jake

    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());

    ?>

  36. Jake

    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>

  37. Soh

    @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 :-(

  38. GreyK50

    Thanks for sharing this Soh.

  39. Kazi Ataul Bari

    woo…………… very nice

  40. Jaspal Singh

    Nice tutorial

  41. Aryata

    extremelly cool

  42. Heather

    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.

  43. DAVE

    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..?

  44. Tushan Kumar

    Thank you to making the animated menu. I liked this animated menu. I think I’ll use it.

  45. Patirck

    If I preview this script in IE7 it will show up in a vertical wide position

  46. Josh Stauffer

    Very cool use of jQuery! I love your tutorials!

  47. Sergey Pimenov

    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]
    });
    });
    });
    })

  48. mark

    just curious if this can be done vertically?

    I was playing with it but couldn’t get it to go.

  49. gymlady

    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 ?

  50. gymlady

    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 !

  51. Soh

    @ Gymlady + Patrick, thats strange. Seems like its working for me…

    IE7 Screen Shot

  52. Anders

    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).

  53. tosca

    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.

  54. Lucks

    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.

  55. sannarts

    here is the post .. still cannot in IE7

  56. Tim

    Thanks for sharing this fantastic technique, works like a charm and only takes 5 minutes to implement!

  57. kaushal sharma

    i salute you boss. cool and fundu…

  58. GeLZa

    oooooo….
    great…
    i love it…. :D

  59. Desfossez Thomas

    @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

  60. Desfossez Thomas

    here, the code :

    $(&quot;#topnav li&quot;).prepend(&quot;&lt;span&gt;&lt;/span&gt;&quot;); //Throws an empty span tag right before the a tag

  61. Tim

    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
    });

  62. rika

    Cool !

  63. Ben

    Great tutorial but what would I do if I wanted to center the navigation?

  64. cooler

    great web site design!!, very clean!

  65. kelvinwebdesigner

    Love your posts. Your website is amazing. Keep writing
    CG

  66. ibkiwi

    Hey quick question. How would I go about controlling the horozontal spacing?

  67. Soh

    @ibkiwi you can add horizontal spacing by increasing the padding size on the ul#topnav a, ul#topnav span ~

  68. fernando

    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

  69. damian

    very nice :)

  70. jun

    very impressive.
    any chance to use current state; when opened a page from menu it should indicate what link is active?

  71. Jin

    Thank you for creating this tutorial site! Thumbs up!

  72. Massimo

    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

  73. Enrique

    Hi
    I’d love to see a dropdown menu example using this menu too…
    Thanks a lot

  74. Dannie

    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.

  75. Ahsan

    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.

  76. piyush

    how to set “current” menu image?

  77. Jonty

    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?

  78. Prince

    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.

  79. aki

    this is sooo cool…! thanks for the tips. hope you could post more of this useful tutorial!

  80. Richard

    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?

  81. Soh

    @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.

  82. unrealxlife

    Very Nice ..

  83. Teknoloji

    Perfect article, thanx

  84. Gemma

    I check with http://validator.w3.org and it shows some error(Invalid)

  85. Imbich

    Greetings. Thanks for a lesson.

    How it is possible to realise animation from top to down (instead of from below upwards)?

  86. Norm

    I found that specifying ‘ul#topnav a, ul#topnav span {width: auto;}’ in my ie6 stylesheet helped. Wish that ie6 would just disappear already.

  87. Jeff

    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!

  88. Alicia

    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/

  89. Kiran

    Hi All

    What about “Current” status apply on menu???????????????????

  90. indialike

    This is really very good… Thanks

  91. wajira

    nice nav bar…. why isn’t working in blogger?

    somebody can help me

  92. Drew

    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.

  93. jomko

    @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;}

  94. Klipsch

    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/?

  95. dr john

    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.

  96. RS

    This is Soh Amazing! :D
    Exactly what I needed! Thank you :D

  97. Ibnts Sy

    //This is very nice. Thanks for sharing

  98. Ozzy

    Awesome tutorial and great explanation of it. I was wondering if was possible to create an active to the navigation.

  99. Chris

    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

  100. tasarım

    nice menu but dosnt work in ie 6

  101. Ary Wibowo

    awesome… thanks :D

  102. Daniel
  103. Aaron Vail

    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

  104. Aaron Vail

    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??

  105. Ivan

    Man I love your work ;D

Speak Your Mind…

Need to post HTML code?
Use Postable for your convenience.

Don't have an Avatar?
Set up a Gravatar image now!

Blog Blog Categories

Popular Comments Popular Posts

Recent Comments Recent Comments