CSS Text based navigation bar with images

Although navigation bars can be styled very pretty using only text and CSS sometimes circumstances might require them to be image based. In this short article I will show you how I create these animated imaged based, navigation bars in an clean and accessible way using images and CSS.

Preparing the XHTML:

Lets pretend to have the following buttons: Home, Services, About Us and Contact Us. I use an unordered list to create the navigation bar, as navigation bars are a list of links, so it’s marked up like this:

<ul id="topnav">
<li id="topnav-1"><a href="home.html" title="Home">Home</a></li>
<li id="topnav-2"><a href="services.html" title="Services">Services</a></li>
<li id="topnav-3"><a href="about-us.html" title="About Us">About Us</a></li>
<li id="topnav-4"><a href="contact-us.html" title="Contact Us">Contact Us</a></li>

Might notice I gave unique ids to the list and it’s elements, this is to be able to style them separately.

Image buttons:

Now lets get our hands on the images. I like to use the “sprite image technique”, because it reduces files count, often reduces file size ( which saves bandwidth ), speeds up page load times, makes it easier to maintain and plus it’s fun! For this example made a very simple 480x40px navigation bar:

Navigation Bar

The three instances of the navigation bar with all its buttons are in one image. Covering the three possible buttons state needed: normal, over and current.


Here comes the magic ingredient, the CSS. It is used to position each button and instance of the navigation bar image in its own link:

ul#topnav {
ul#topnav li {

The following step is to add the general rules for the links. Float to the left, shift their text -9999px to hide it put it out of the screen:

ul#topnav li a {

Now as each link has a different width size and background portion have to enter the correct values to each of them with width and the CSS background property. Made a simple schema to show you from where I get values used ( click to enlarge ):

ul#topnav li#topnav-1 a {
background:url(images/nav.jpg) no-repeat 0 0; /* X and Y position at 0 */
ul#topnav  li#topnav-1 a:hover {
background-position:0 -40px; /* Y position -40px for Over instance image */
ul#topnav  li#topnav-1 a.current {
background-position:0 -80px; /* Y position -80px for Current instance image */

As you see above, defined 3 rules for the first button: #topnav-1. First rule sets the width of the link and its default background. Second rule, a:hover changes the background’s Y-position to -40px for the over state and lastly the a.current changes the background’s Y-position to -80px for the .current class effect.

Remember :hover and :active are pseudoclasses while .current is just a regular CSS class we add to the to difference the selected element from the the rest.

Now to the same workflow the rest of the buttons, keeping in mind that each button have its own width and background X-position. A very quick easy way to get this last value is to get the previous button background X-position and its width and substract them. For example:

#topnav-2 will be: 0 ( previous button background X-position ) – 106px ( previous button width ) = -106px.

#topnav-3 will be: -106px ( previous button background X-position ) – 116px ( previous button width ) = -222px.

ul#topnav li#topnav-2 a {
background:url(nav.jpg) no-repeat -106px 0;
ul#topnav  li#topnav-2 a:hover {
background-position:-106px -40px;
ul#topnav  li#topnav-2 a.current {
background-position:-106px -80px;
ul#topnav li#topnav-3 a {
background:url(nav.jpg) no-repeat -222px 0;
ul#topnav  li#topnav-3 a:hover {
background-position:-222px -40px;
ul#topnav  li#topnav-3 a.current {
background-position:-222px -80px;
ul#topnav li#topnav-4 a {
background:url(nav.jpg) no-repeat -344px 0;
ul#topnav  li#topnav-4 a:hover {
background-position:-344px -40px;
ul#topnav  li#topnav-4 a.current {
background-position:-344px -80px;


Hope you find this post useful, thanks for stoping by!

This technique has been tested in: IE6, IE7, Firefox ( Mac/PC ) and Safari ( Mac ).

Reactions (51)

  1. Pingback CSS Text Based Navigation Bar With Images : Freelance Folder

  2. Nice article! :)

    One thing… Because support is so inconsistent between current and older browsers it’s not a good idea to use underscores in class or ID names. I’ve heard that old V’s of Navigator don’t recognize it – same with some old versions of Opera too.

  3. Pingback Image based CSS navigation bar.

  4. Nice article! :)

    One thing… Because support is so inconsistent between current and older browsers it’s not a good idea to use underscores in class or ID names. I’ve heard that old V’s of Navigator don’t recognize it – same with some old versions of Opera too.

    Thanks for the heads up James! Post updated. Will surely take this into consideration in future projects.

  5. thanks for the so good explanation that you have done in this tutorial. :)

  6. thanks for the so good explanation that you have done in this tutorial. :)
    Woah, you’re first article is a pretty solid ressource. Keep it up!

    Thanks for the kind words :)

  7. omg! thanks so much for this template. I’m a beginner/intermediate designer and I’ve been searching for help with an image based nav bar for a week now. Very easy to follow and the graphic was most helpful in grasping the whole concept….especially background position x & y coordinates.

    thanks again!

  8. Pingback CSS menu framework and Navigation bar code generator - WittySparks

  9. Thank you!! this is an excellent article man, this save me a lot of time, greeting from Costa Rica =)

  10. martin

    Hi Matt, this is great! This post has been really helpful. I’m just a beginner but your text is as clear as water. One doubt, though.

    Is it possible to use this with more that 5 links/buttons? I ask you because I managed to make it work with 5 (I was aiming 7 but the last 2 don’t show up) and I don’t seem to be able to get my 7 buttons.

    I need a yes-or-no answer, if itś a yes I’ll keep on trying.

    Thanks in advance, martin.

    • Hi Martin, Thanks for stopping by, im glad you found the tutorial useful. The answer is Yes you can. As for this first time you could try using the CSS Navigation Bar Code Generator and then investigate the generated code.


  11. martin

    Thanks Matt, I’ll just do that and go from there. I gave it a try last night but it was really late and I don’t think my lights were on at that time! :)

    Thanks for your answer.

  12. Done it! Thanks a bunch! The only thing I can’t get to work yet is the “current state”. It doesn’t change when I change the pages or whatever but I still need to see how that works.

    Thank you for these tutorials!

  13. Thanks for excellent work.
    I’ve got the problem, trying create horizontal menu. After uploading my JPG file (GIMP-created) , there is only one option “VERTICAL” and further work does not have sense.

    • Hi Tomasz. Thanks for the nice words.
      Is your horizontal navigation bar vertical height divisible by two or three? if you want send me then image to contact@mattvarone.com and i will check it out.

  14. Hi Matt,

    Thanks for your excellent work! Very easy and user-friendly. It was fantastic : I had no problems making the navbar and then locally substituting GIFs for the JPEGs (they were too muddy, sadly).

    However I am having issues getting the navbar to center on my page, under the header image : it’s too far to the right. I’ve enclosed it in a div called “nav”, but that doesn’t seem to make any difference… Also, there seems to be a vertical space of 10-12 pixels above the navbar, and I can’t figure out where it’s coming from.

    I’m more of a Flash developer than HTML, and I’d appreciate a little help on this if you have a second. I can return the favour one day if you ever need Flash help or advice :-)

    The pages and the associated stylesheets are online here :

    Would you mind taking a look?
    Thanks VERY much in advance!

    Ric Zito

  15. Thanks, I tried the generator and it works great. I cannot open the downloaded zip file though? Any way to make this work?

    • Hi RM, thanks for the comment. See if you can try decompressing the zip file with another program. I noticed some treat the file as corrupted but havent got to look much into it. Let me know if that worked for you.

  16. Yes, that worked. Thanks for your help! Now if you would please allow this thing to upload png files, I’d be stoked.!

    Im not sure if it would be easy or not to use your generator and then match up my png files to your generated jpgs…


  17. I get that you can design how your nav bar would look using css but what I don’t understand is how you go about changing 100 pages in a site when a customer wants to add or delete a button? css is just for the design aspect, no? I just had this client ask me to get rid of her “purchase” page. Luckily there were only 20 pages in her site – but it got me to thinking, what if there were 100 or something. I had to go into each page and delete that button. should I use a template for the buttons? or is there something in css class I missed. Thanks…

  18. That saved a bit of time – thanks for the useful tool Matt.

  19. Pingback Image navigation bar

  20. Sweet tutorial! Coming from someone without much experience in this regard, I found it really easy to follow. Any thoughts on the best way to integrate this type of navigation with content below it? I’m told iFrames are not the way to go anymore, but am curious the best way to preserve the page state without recreating the menu on each page so the “active” page remains active (the image shows the proper page as being active)

  21. You bloody genius, been looking for this everywhere. Plenty tutorials on the rollover bit, but the part i was stuck on was maintaining the a ‘selected’ state for different pages, which you fixed so simply.

  22. Ryan Egan


    My nav bar wasnt centering in Safari, so I set it’s margin-left to -40px. It looks all right in Safari but in IE it’s not 40px to far on the left side of the page.

    Any ideas? Sorry, I’m really new to this!

  23. I’m completely and totally confused on the -40px thing. I’m using Expression Web 2 and IE 8 to develop and proof my site, and using a horizontal nav bar (thank you, Matt!!). I’ve tried the solution above, but it doesn’t seem to work for me. The following is just under my title, and I have the referenced files where they should be:

    Yet, when I check the page in IE8, the nav bar is sitting to the right by 40 px. When I turn on compatibility view, it slides back where it should.

    Any help would be MUCH appreciated!

  24. Can I use the CSS in wordpress? Prob a lame question but I am new to this and want to add a menu with images and your generator seems perfect. I have the files on my computer. I put the jpg in my images folder for the theme. But how do I get the menu working on my page? Where do I put the CSS file? Thank you so much!

  25. I’m having exactly the same issue of it being nudged c. 40px to the right. I’m wondering – where does this number come from? I’ve built the navbar manually, not using the generator – it must be somewhere within how I’ve put it together, right?

  26. Matt
    Is there a way to have a dropdown menu with rollovers images from the rollover nav bar?

  27. Pingback CSS Navigation Code Generator

  28. Matt

    Seems to be a bug (feature?) with your code output and the most recent version of FF(3.6.x) MAc – works fine in SF and IE8 on the PC.

    Pulled my hair out until I added

    ul#topnavigation li {
    margin: 0; <—-this &
    padding: 0;<—-this

    To the CSS. Otherwise the last button in my list would be knocked down by the implicit in the bacground that is not visible since the text is way off in left field with the -9999 used.
    This drove me nutso especially when I found out how simple the fix was ….. blech
    Otherwise a great time saver!


  29. Great article Matt,

    Understandable and clean. Keep up the great work

  30. Hi,
    This is AWESOME!!!! Thank you!
    Can you please share how to add sub-menus to this very cool navbar? I’m quite sure I will break the code if i try my own experiments!!! Better to leave some things to the EXPERTS!
    Thank you very much!

  31. I’ve been looking for this! Thanks!

    I’m having some phantom space on top of the navigation bar though, like approx 5 pixels in height. It seems to even have a space underneath it as well, as my content gets pushed lower. This only happens in IE though.

    I tried using CSS resets, but that only got rid of the -40px problem that a few people have been having here.

    Anybody here figured this out?

  32. My links doesnt work now?? What happened? The button worked for a few minutes but now they are only like an image.

  33. David Hughes

    This is an awesome improved version of the old method of doing this. I know the article is 2 years old now, but I just stumbled across it and it works, perfectly.

    I only wish I had found it earlier, would have been very useful!

    Thank you so much for this, it’s a huge help.

  34. You just saved my sanity – I spent the last 24 hours trying to figure this all out. THANK YOU for sharing this great resource!

  35. Very cool menu generator. One problem I have though – I use a DW template with the menu in it – so the menu is the same on every page. I can’t move the class=”current” tag to a different link for each page.

    So I had to take each:

    ul#navbar li#navbar-1 a.current {
    background-position:0px -80px

    remove the class:

    ul#navbar li#navbar-1 a {
    background-position:0px -80px

    and put that in the editable region in the head of each page

  36. Rob Stathem

    This is a GREAT tutorial, and I’m going to bookmark it! Thanks Matt! :)

    This is a bit off topic, but on the path of CSS and navigation. How does one create custom image bullets in between a horizontal navigation? I’m going to do a bit more research on this, but using background images for the actual list items puts bullets for EACH separate link, thus defeating the purpose of adding bullets “in between” a horizontal list. Even by using custom image bullets for the list items does not provide full placement/positioning control. Percentages might get you more accuracy, but it does not place bullets directly in the middle of each list item.

    Thank you so much,

  37. HI Matt

    This is a great tutorial and I have created my bar.

    I have a problem…I’m no expert with html or css and I have created my website using iWeb and wondered if it was possible to get my menu bar into that. If so my next problem would be how to do it. I have no idea how it needs to be structured to work. Does the css and xhtml code go into the iWeb html snipet or does the XHTML bit only go in there and then the css in your folder? I’m stuck. My bar is exactly how I want it, but don’t know what to do next…

    Can you help me with the structure?