Picnic Website Code Tutorials

How To Make a CSS Sprites Navigation Menu

View Demo

Directly below is a condensed version of the image I used, and here is how to make it!

CSS Sprites Image

As you can see, all the menu states are contained within this one image. As with some other sprite menus of it's kind, I'm hiding the text with a combination of height and overflow hidden on the #nav, and padding-top equal to the height of the image on the anchor. This type of image replacement only fails in the CSS On/Images Off scenario. Or, you can also use text-indent -999em with the same results. To date, this is the most complete and cleanest coded sprite navigation in existence - I kid thee not!

The CSS

* {
margin:0;
padding:0;
}
body {
background:#eee;
}
#nav {
list-style:none;
width:750px;
height:50px;
margin:20px auto;
overflow:hidden;
background:url(images/nav.gif); /* IE6 Flicker Fix */
}
#nav li {
float:left;
}
#nav a {
float:left;
width:150px;
padding-top:50px;
outline:0;
background:url(images/nav.gif);
}
/* Default State */
#nav #a{background-position:0 0;} 
#nav #b{background-position:-150px 0;}
#nav #c{background-position:-300px 0;}
#nav #d{background-position:-450px 0;}
#nav #e{background-position:-600px 0;}
/* Hover/Focus State */
#nav #a:hover,#nav #a:focus{background-position:0 -50px;}
#nav #b:hover,#nav #b:focus{background-position:-150px -50px;}
#nav #c:hover,#nav #c:focus{background-position:-300px -50px;}
#nav #d:hover,#nav #d:focus{background-position:-450px -50px;}
#nav #e:hover,#nav #e:focus{background-position:-600px -50px;}
/* Active State */
#nav #a:active{background-position:0 -100px;}
#nav #b:active{background-position:-150px -100px;}
#nav #c:active{background-position:-300px -100px;}
#nav #d:active{background-position:-450px -100px;}
#nav #e:active{background-position:-600px -100px;}
/* Current Page */
#home #nav #a{background-position:0 -150px;}
#about #nav #b{background-position:-150px -150px;}
#services #nav #c{background-position:-300px -150px;}
#map #nav #d{background-position:-450px -150px;}
#contact #nav #e{background-position:-600px -150px;}
		

The HTML

<ul id="nav">
  <li><a href="#" id="a">HOME</a></li>
  <li><a href="#" id="b">ABOUT</a></li>
  <li><a href="#" id="c">SERVICES</a></li>
  <li><a href="#" id="d">MAP</a></li>
  <li><a href="#" id="e">CONTACT</a></li>
</ul>
		

...Or Even Better!

View Demo

Looks the same right? Well here's how it's different! Up until today, there was NO known image replacement technique for a sprite navigation menu that worked in the CSS On/Images Off scenario. That is, if you also wanted to use :focus and :active pseudo-classes (which I did here in this menu!), because active/focus only work reliably/cross browser when applied to the anchor. This basic idea (position absolute) started with Paul OB's image replacement, but I recoded it with added support for :active and :focus. And I'd like to thank my buddies over at Sitepoint for helping me work out the kinks.

This method works perfect (with no loss in accessibility or other) in all situations - CSS On/Images On, CSS Off/Images On, CSS On/Images Off, and CSS Off/Images Off! That is, all except IE6 of course. Because of it's inevitable image flicker (which we hid before with the sprite.gif on the #nav as well), you can see the text behind the image briefly with each flicker. So, IE6 gets left:-999em which leaves her no worse off than she's been since sprites were invented! I coin this the Spriteric Image Replacement! Simply add this code below to implement...

The CSS

#nav li {
position:relative; /* make the "b" relative to the "li/a" */
}
#nav a {
height:50px; /* replace padding-top with height (or IE6 chokes) and remove height off #nav */ 
text-decoration:none; /* it now behooves us to style the text */
color:#000; /* more style */
}
#nav a:hover b, #nav a:focus b { /* the b here is necessary for IE8/Opera */
font-size:120%; /* more style */
}
#nav a b {
position:absolute; /* the magic */
left:0;top:0; /* the magic */
z-index:-1; /* the magic */
height:50px; /* same height as anchor */
width:150px; /* same width as anchor */
line-height:50px; /* more style */
text-align:center; /* more style */
}
* html #nav a b { 
left:-999em; /* IE6 Fix */
}
		

The HTML

<ul id="nav"> <!-- Spriteric Adds the b's -->
  <li><a href="#" id="a"><b>HOME</b></a></li>
  <li><a href="#" id="b"><b>ABOUT</b></a></li>
  <li><a href="#" id="c"><b>SERVICES</b></a></li>
  <li><a href="#" id="d"><b>MAP</b></a></li>
  <li><a href="#" id="e"><b>CONTACT</b></a></li>
</ul>
		

Sponsors

Top Donators

Friends of Mine