Fading Navigation Menu

Fading Navigation Menu
For my first tutorial, I have decided on building a simple, yet awesome navigation menu using CSS sprites. After we are done with this I will add a bit of jquery code to give it a visually appealing fade effect. I have included the .PSD file I created in the download under the images folder to make it easier for you to create your own Fading Navigation Menu.

What is a sprite?

In case you aren’t sure, a CSS sprite is a large image, made up of all the smaller images you wish to use on your webpage. The benefits of using CSS sprites include:

  • Page load speed
    • Reduces HTTP requests
    • Each image file contains extra unnecessary information. Using one image saves on file size.
  • Save on editing time
    • If I’m working on a navigation menu and I need to edit the hover states in photoshop, all I do is edit one of the layer styles and paste it over the rest of the button hover states, save and all is done. Doing this takes a matter of seconds.
  • Easier to organize
    • The more files there are, the greater the margin for confusion and error is. Also, I don’t enjoy a messy work environment.

Step 1 – The HTML

Alright, let’s get started.

First thing we need to do is create the html.

<ul id="nav">
    <li class="home"><a href="#">Blog</a></li>
    <li class="about"><a href="#">About</a></li>
    <li class="contact"><a href="#">Contact</a></li>
    <li class="freebies"><a href="#">Freebies</a></li>
</ul>

It is a very simple unordered list and I have given each of the list items class names so that we can target them individually.

The sprite we are going to be using is this one that I created:

I usually create a red grid around the items to make it easier to determine where the one ‘image’ begins and the other one ends.
We give the CSS the x and y co-ordinates of our sprite, this is how it knows which area to look at. Since each list item has a different class, we can target each of them and give them different sprite background-positions.

Step 2 – The CSS

I always import a css reset. I use a modified version of Eric Mayer’s CSS reset which include with these downloads.

ul#nav li, ul#nav li a { background: url(../images/nav-sprite.png) no-repeat left top; height: 67px; width: 192px; } /* We give the <li> and <a> the sprite as the background and set the button dimensions */
ul#nav li { float: left; border: 1px solid #243e3b; border-left: none; }
ul#nav li.home { border-left: 1px solid #243e3b; }
ul#nav li a { display: block; text-indent: -9999px; }

ul#nav li.home a { background-position: -1px -1px; } /* Here we set the background/sprite position */
ul#nav li.about a { background-position: -194px -1px; }
ul#nav li.contact a { background-position: -387px -1px; }
ul#nav li.freebies a { background-position: -580px -1px; }

ul#nav li.home a:hover { background-position: -1px -69px; } /* And now the hover background-position position */
ul#nav li.about a:hover { background-position: -194px -69px; }
ul#nav li.contact a:hover { background-position: -387px -69px; }
ul#nav li.freebies a:hover { background-position: -580px -69px; }

That’s it! We have a working CSS sprite navigation menu.
Demo CSS version / Download CSS version

Step 3 – The jQuery

Before we do anything more, remember to always include the jQuery library when using any jQuery plugins or code.

We have to slightly modify the CSS before we can make us of the cool fade effect.

First we have to decide how we will go about creating the effect. I think the most efficient way would be to give the <li> item the default background state and the <a> link the hover state with an opacity of 0. When we hover it will fade to an opacity of 1, and when we mouse off it will fade back to 0, giving the fade effect.

We slightly modify the CSS selectors to look like this:

ul#nav li, ul#nav li a { background: url(../images/nav-sprite.png) no-repeat left top; height: 67px; width: 192px; }
ul#nav li { float: left; border: 1px solid #243e3b; border-left: none; }
ul#nav li a { display: block; text-indent: -9999px; }

ul#nav li.home { background-position: -1px -1px; border-left: 1px solid #243e3b; }
ul#nav li.about { background-position: -194px -1px; }
ul#nav li.contact { background-position: -387px -1px; }
ul#nav li.freebies { background-position: -580px -1px; }

ul#nav li.home a { background-position: -1px -69px; }
ul#nav li.about a { background-position: -194px -69px; }
ul#nav li.contact a { background-position: -387px -69px; }
ul#nav li.freebies a { background-position: -580px -69px; }
$(document).ready(function(){ 

	//Set the anchor link opacity to 0 and begin hover function
	$("ul#nav li a").css({"opacity" : 0}).hover(function(){ 

		//Fade to an opacity of 1 at a speed of 200ms
		$(this).stop().animate({"opacity" : 1}, 200); 
	
		//On mouse-off
		}, function(){

		//Fade to an opacity of 0 at a speed of 100ms
		$(this).stop().animate({"opacity" : 0}, 100); 
	
	});
	
});

stop() is necessary so that the animations don’t queue up if you mouse-on and off repeatedly very quickly.

And we are done in 3 easy steps. Pretty simple right?

What say you?

  1. Lucas says:

    Nice tutorial bud!
    I might just use this.

    Hope to see more stuff!

    1. Jamy Golden says:

      Thanks, there is definitely much more on the way!

  2. BerniBall says:

    Hey this is great, but how could I go about making it so the text between <a href=”#” rel=”nofollow”></a> tags isn’t hidden?

    It also has it’s opacity made 0 upon loading the page. I only want to effect the background image.

    Any ideas?

    1. Jamy Golden says:

      It’s the ‘text-indent’ CSS property that is ‘hiding’ the text. If you remove it, the text will come back.

      What you’re trying to do is actually pretty tricky. If you bring back the text (Get rid of text-indent), you will notice that it is only visible when you hover over it (the active state).

      I’ve never come across a jQuery plugin that allows one to animate background-images (Fade on into another), however there are plugins available that allow background-color animation. (This doesn’t come with stand-alone jQuery either).

      I think you would be able to do this with CSS3 transition, however, I haven’t tried this with background-images yet.

      In short, You will have to stick with flat background color fading in and out if you require actual text.
      Alternatively, you could find another long winded way to do it they way you would like, but it’s not going to be very semantic code and I don’t think it will be worth the energy.

      I hope this all makes sense :)

  3. Jen Frey says:

    Great tutorial! Very easy to follow and easy to change up as needed. Thanks for doing this :)

  4. John says:

    Hi thanks for the great tutorial.

    I have implemented a menu with an additional state being ‘Selected’ so when you click on one of the menu items for example “About” and the “About” page loads I wanted to have a selected state on the menu.

    I have tried the following but it doesn’t seem to work:

    <a href=”#” rel=”nofollow”>About</a>
    #nav li.aboutus a.selected {background-position:-473px -162px;}

    Any help you can give me I would appreciate it.

    1. Jamy Golden says:

      This might work, add this to your <head> section:

      <script type="text/javascript">
      $(function(){
      	$('#nav').find('a').each(function() {
      		if(this.href == window.location)
      		$(this).addClass('selected');
      	});
      });
      </script>

      That will highlight any link within #nav that contains the same url as the current url. Quick and easy current page highlighting :)

  5. Kurt says:

    Great Tutorial, love it!!!.

    this is what i’m making http://preview.ling3r.com/torsobuild/index.html

    this is the CSS

    http://preview.ling3r.com/torsobuild/styles/styles.css

    Works great in chrome, but the dot point for the is showing in IE9 and FF4

    i have tried upping the text-indent and changing its color to the same as the background but neither worked

    any help would be great!

  6. Kurt says:

    got it working!

  7. haldun says:

    Useful tutorial! thanks! Is it possible to animate css-sprite like this:
    #circle1{
    background-image:url(circle1.png )no-repeat;;
    background-position:top left;
    }

    #circle1:hover{
    background-position:top right;
    background-repeat:no-repeat;
    }

    if the id is hovered background top left with an affect. I have tried to do this with your tutorial but cant work it out just as i want..Any tip?
    Thnx

    1. That should work, the only error I see is background-position: top right;. It should be: background-position: right top;. So it’s background-position: x-axis y-axis. You also have a double semi colon in there, but that was probably just a typo in your example.

  8. CT says:

    Hey great plug-in. I was wondering can you put more than one on the same page?

    1. Jamy Golden says:

      Hey, yeah you can. Just make sure they have different ids (Or you target them differently with the jQuery). For example, if you had a navigation named #primary and another named #secondary. You would have the following jQuery:

      $(document).ready(function(){ 
      
      	//Set the anchor link opacity to 0 and begin hover function
      	$("#primary a, #secondary a").css({"opacity" : 0}).hover(function(){ 
      
      		//Fade to an opacity of 1 at a speed of 200ms
      		$(this).stop().animate({"opacity" : 1}, 200); 
      
      		//On mouse-off
      		}, function(){
      
      		//Fade to an opacity of 0 at a speed of 100ms
      		$(this).stop().animate({"opacity" : 0}, 100); 
      
      	});
      
      });
    2. CT says:

      Works perfect! Thanks a lot!

  9. Irfan says:

    hi Jamy.
    I work on a ERP solution and for our recent project, i developing a web based ERP system, and i use jquery for cross browser issue, i am new to jquery and web based programming, i need to create a Navigation menu with sub menu items can u help me on this stuff how to make it in jquery

    1. Jamy Golden says:

      Hey, I think this article should help.

  10. Rob R. says:

    I’ve been looking for something like this for a while. I really like it. I am, however, having the same problem as Kurt above – It’s fine in Chrome, but I’m seeing the bullet point in Firefox and IE. Your demo renders fine in all three browsers. What am I doing wrong?

    1. Rob R. says:

      I figured it out. ( list-style: none) if anyone else wonders.

    2. Jamy Golden says:

      Thanks for adding the answer :p

  11. raman says:

    Nice creation, can you apply CSS fixed property

    1. Jamy Golden says:

      You totally can.

  12. Nishi says:

    Hey, fantastic tutorial man! Exactly what I was looking for. One quick question though: is there a way to make the opacity of one of the nav items increase or decrease depending on the scrollbar position? I’m making a single-page personal portfolio, and I’d like the ‘portfolio’ link to change to the hover state when on the portfolio part of the page, etc, and stay in that state until the user moves to a different section.

  13. Meagan Roach says:

    Hello,

    First off thank you so much for this! I have been at trying to do a simple rollover fade for the entire day! Every other one is so long winded, but yours is clean and simple.

    I do have a question however. I am using on a personal site. http://www.meaganroach.com is there any way to get out that glitchy instance between the fadeout-fadein. It jumps back to the background position at 0 0 for a millisecond before fading out.

    Thanks again so much! If you ever need some design work feel free to ask!

    1. Jamy Golden says:

      Hi! Thanks for the offer :)
      I think the problem is this line:

      $(this).stop().animate({"opacity" : 0}, 0); 

      The duration is set to 0. Try changing it to 400:

      $(this).stop().animate({"opacity" : 0}, 400); 

      Let me know if that helps. If not let me know!