The fun part of CSS (if you’re a weirdo like me and get a kick out of this sort of thing) is coming up with the most optimized, cleanest, accessible, and compliant code that you possibly can. This tutorial will show you one of my favorite ways of doing a navigation menu with image rollovers done in CSS that uses only one image and very minimal HTML / CSS code. This is by no means the only way of going about it, nor is it the “right” way if there is such a thing, but I’ve found this to be a very quick and efficient way of accomplishing our task.
This article is the first of a 2 part series, and the second half will apply this tutorial into creating a CSS only dropdown menu navigation with the image rollovers that is compliant with IE6 and up.
Click here to see a demo of what we’ll be doing.
The first trick is to make your navigation image. The best way of going about this is to create your menu in photoshop, double it’s width (or height if you are doing a horizontal navigation), and then paste the exact same thing with ever link in its rollover state right next to it. It should look something like this. This makes for quicker load time than if you did every image separately and even less CSS needed.
Next we will write all of the HTML out:
<ul id="navigation">
<li><a href="index.php" class="link1">Home</a></li>
<li><a href="metal" class="link2">Metal</a></li>
<li><a href="plastic" class="link3">Plastic</a></li>
<li><a href="services.php" class="link4">Services</a></li>
<li><a href="news.php" class="link5">News</a></li>
<li><a href="catalog.php" class="link6">Catalog</a></li>
<li><a href="about.php" class="link7">About Us</a></li>
<li><a href="contact.php" class="link8">Contact</a></li>
<li><a href="users.php" class="link9">Registered Users</a></li>
</ul>
I always set up my navigation menus in unordered lists. Normally just one ‘id’ on the ‘ul’ tag would be enough HTML, but in the case of each link having its own background then each link has to have its own class.
Here is the CSS for our menu:
#navigation {
border-right:1px solid #999;
padding:10px 0px;
width:145px;
}
#navigation a {
display:block;
background:url(navigation.png);
height:47px;
text-indent:-9000px;
}
#navigation a.link1:hover {background-position:-146px 0px;}
#navigation a.link2 {background-position:0px -47px;}
#navigation a.link2:hover {background-position:-146px -47px;}
#navigation a.link3 {background-position:0px -94px;}
#navigation a.link3:hover{background-position:-146px -94px;}
#navigation a.link4 {background-position:0px -141px;}
#navigation a.link4:hover {background-position:-146px -141px;}
#navigation a.link5 {background-position:0px -188px;}
#navigation a.link5:hover {background-position:-146px -188px;}
#navigation a.link6 {background-position:0px -235px;}
#navigation a.link6:hover {background-position:-146px -235px;}
#navigation a.link7 {background-position:0px -282px;}
#navigation a.link7:hover {background-position:-146px -282px;}
#navigation a.link8 {background-position:0px -329px;}
#navigation a.link8:hover {background-position:-146px -329px;}
#navigation a.link9 {background-position:0px -375px; height:65px;}
#navigation a.link9:hover {background-position:-146px -375px;}
Now for the broken down detailed explanation of the CSS:
- The border and padding on the #navigation is simply for looks on this menu
- The width on #navigation is set to the size of our whole nav menu
- #navigation a lets us apply the following styles to every link within the ul
- Display:block is an extremely useful property in many situations. It will change the element into a block level element, i.e. it will act like a div. We can now apply styles to a link that we couldn’t have before.
- Background:url(navigation.png) sets the background for each link
- The height is important, otherwise the link will only be the size of the text by default. In this case, the links’ width is determined by the containing ul’s width.
- Text-indent:-9000px moves the text within the anchor tag off of the page which allows search engines to still have something to index
- Lastly, the key to this CSS strategy is changing the background-position separately for every link and its hover state. For example, #navigation a.link3:hover{background-position:-146px -94px;} tells the browser to move the background image on our 3rd link’s hover state 146 pixels to the left and 94 pixels up. These numbers are all determined by the size of each link, e.g. each link’s background position is 47 pixels higher than the one before it because that is the height of our links.
That’s it! Probably the trickiest part is setting up your image and getting the pixels right on the background positions. If you have any suggestions, comments or questions, please leave them! If you stumbled upon this little gem, make you check out CSS Navigation Rollovers With Drop Downs where we use this rollover technique in a tutorial to create CSS drop downs.
Site is looking slick buddy. Totally subscribing to your RSS feed. Also twittering it.
im jst posting to see that weird post bg effect…
tis cool
This is just what i am looking for. But my Nav is More Vert then Horz I can not figure out how to make it work for me in that way.
John,
I’m assuming you meant your navigation was horizontal, not vertical? Because the demo here shows a vertical navigation. My best advice is for you to take a look at how I did the navigation on this website with Firebug (tool has a million uses for learning how others did their CSS). All you really need to do is make sure that each item has a width, and then float all the li’s to the left and they will bump up against each other horizontally.
I got it to work.
http://trapdoorinteractive.com/newwebsite/index.html
Not done yet but your code help a bunch
Glad I could help. First thing I noticed when I looked at your navigation: you should be using PNG’s for that kind of an image, not a JPG. PNG’s are good especially for vector elements like text, and things that don’t have a ton of different colors in them. You’ll get a smaller file size and you won’t see the lossy effect around the text like you get with a compressed JPG.
ok awsome
This is a cool tutorial.
I may use this for some of my future projects.
Keep it up.
Hi Joren
Thanks for a cool tutorial. I used it for the navigation of this site and it actually links to the pages, but the navigation image does not display. I am not sure what I am doing wrong. I am not really experienced with this so I am not sure where to look for my error. Thanks again.
Under ‘#navigation a’ you specify its background as url(navigation.png). Navigation.png does not exist, at least not in the same folder as your CSS file, so you have to point it to the background image correctly. So, say you have your CSS file in a CSS folder, and the image in an Images folder, and they’re both in your document root, then it should be something like url(../images/navigation.png). Make sense?
Thank you!!!! I’m an idiot! Fixed it, and it works perfectly. Thanks for responding so quickly. Awesome site!
Cool, looks good too
Hi Joren,
This is exactly what I was looking for, and works like a charm for me in Firefox! But…it’s misaligned in Internet Explorer. I can’t figure out what’s wrong. Any ideas? Here’s my site & code:
http://www.blueskyhigh.com/
HTML
Home
Blog
Wine Bar
About
CSS
#navmenu{
padding: 0 0 10px 0;
list-style-type: none;
/*border: 1px solid #ff6600;
background: url(”images/black80.png”) repeat fixed;
background-position: top left;
background-position: auto;
background-overflow: hidden;*/
}
#navmenu a{
float: left;
background: url(”images/BSHeader_bottom.png”) no-repeat;
height: 25px;
text-indent: -9000px;
}
#navmenu a.link1 {
background-position: 0px 0px;
width: 186px;
}
#navmenu a.link1:hover {
background-position: 0px -31px;
width: 186px;
}
#navmenu a.link2 {
background-position: -186px 0px;
width: 409px;
}
#navmenu a.link2:hover {
background-position: -186px -31px;
width: 409px;
}
#navmenu a.link3 {
background-position: -595px 0px;
width: 199px;
}
#navmenu a.link3:hover {
background-position: -595px -31px;
width: 199px;
}
#navmenu a.link4 {
background-position: -794px 0px;
width: 196px;
}
#navmenu a.link4:hover {
background-position: -794px -31px;
width: 196px;
}
Thanks in advance for your help!
Hmm, try floating the list items to the left instead of the anchors, and give the anchors display:block;. And make sure that all the anchors do not add up to a width larger than your container and you should be alright.
You’re my boy, Joren! I added “#navmenu li{float: left;}” and that did it! Thank you so much for this. I think I’m ready to launch.
For a future enhancement, do you have any suggestions for how to make the current nav image remain highlighted when it’s not hovered?
Thanks again!
You mean change the background image to the rollover state of whatever page the user is currently on?
Exactly!
Well, if you’re using a template system and can’t modify the navigation’s HTML for each separate page, then you’ll have to create a javascript function that changes the background position depending on what page the user is on, and load that function with a different parameter for each page. This can be accomplished pretty easily with jQuery.
OK, great. I will look into that sometime in the future. Again - thanks for your help. Great site!
Hi Joe,
Thanks very much for your tutorial. I followed it and achieved the menu on http://www.agapebiblechurch.info but I am having issues with the positioninig. Please can you help me out.
Thanks very much
Heh, I have no idea where this Joe comes from. . . your not the first person to do that. Anyways, you’ll have to be more descriptive, I don’t know what you’re trying to achieve on that link.
Ok sorry Joren, I followed your navigation example and got that result, I still can’t figure out where the problem is with my scripts. Please can you help me.
Barry, I don’t know what the problem is, so if you want me to help you fix it, you have to actually tell me what it is that’s wrong.
The problem with the navigation is that it’s suppose to have same height with the animation div. but i don’t know exactly what i am doing wrong. It hangs in between the both thereby not looking nice.
Thanks for your help. if you require the source code, you can view it.
Hi Joren,
Like your work here, Is it possible to add an active state to this, so when in a page it stays the same to show you are on that page.
Thanks for any advise Andy.
Thanks! Yes, all you would need to do is make room in the sprite image for a third row of navigation, and then just add a class to the specific link that its state changes on each page, then just give that active class new background-position properties.
However, if you have the links coming through on an include or dynamic and you can’t manually add a class for each page, then you could add the class via a javascript function which is what I normally do.
[...] CSS Navigation Image Rollovers [...]
[...] CSS Navigation Image Rollovers [...]
[...] Super Fantastic CSS Navigation Image Rollovers [...]
[...] CSS Navigation Image Rollovers [...]
[...] Super Fantastic CSS Navigation Image Rollovers – A quick and very optimized way of creating your navigation’s mouse overs using just one image and CSS. [...]