CSS has given designers access to styling typography that was unheard of many years ago. But sometimes you will want to use a unique font face for your site navigation that will probably not be available across all platforms. In the past, you would layout your navigation in Adobe Photoshop, slice them up, and place inline graphics in a table in your mark up. And, to add rollover functionality, you would have to use a javascript. We now know that this is not the semantic way to mark up a page. A table should only be used to present tabular data and not for layout and presentation. A list of links should be inside either the <ul> or <ol> and should be a list of text links, not a list of graphics. Do you abandon the idea of using typography for your navigation? Absolutely not. You can still achieve this effect, without using a javascript, and keep your mark up 100% semantic with CSS.
The Tutorial
This tutorial is extensive and intended for designers and developers who are learning CSS. We are going to be using the “image replacement” and “sliding door” methods to achieve the effect. Here are the tools you will need to follow along.
- Adobe Photoshop (preferably CS2 or CS3) to create the graphics.
- Download the free typeface, Heroin 07, from dafont.com.
- A code editor to write all of your markup and CSS. I use TextMate by MacroMates, but you can use the code editor you are comfortable with.
- For testing, I am going to be using the latest version of Mozilla’s Firefox with the Web Developer Add-on installed. (Note: If you do not have either, I strongly recommend downloading and installing them. This will save you hours of time debugging your code.)
Step 1: Set up your new document in Photoshop

We are going to create a simple navigational bar that will have three options: Home, About and Contact. Launch Photoshop and from the top menu select File – New to open the New Document dialog box. Enter the following information:
- Name: nav-bar
- Preset: Custom
- Width: 495px
- Height: 72px
- Resolution: 72ppi
- Color Mode: RGB
- Background Content: Transparent
- Click “OK”.
I want to divide the document in thirds, knowing that there will only be three options, and I want to make sure that my buttons are properly spaced apart. So, select New Guide… from the View menu option and let’s place a guide at 165px (orientation: vertical) and another one at 330px (orientation: vertical). Now, I want to divide the document in half horizontally to give me a guide for the rollover image. Place a third guide at 36px (orientation: horizontal). Right click on Layer 1 to open the Layer Properties dialog box. Rename this layer “Background” and click “OK”. Finally, with Layer 1 still selected, click on Edit – Fill… and choose Black from the pull down menu. Your document should look like the image below.

Step 2: Adding static and rollover state text

Now we are going to add the text for the buttons in both their static and rollover states. One of the drawbacks of using a CSS only method, for creating a rollover effect, is that there will be a slight flicker when the end user moves the pointer over the button. This flicker delay is caused by the browser needing to load the second image for the rollover. Once the rollover image has been loaded, it will be saved in the cache and you will no longer see the flicker. But, this is not what we want. We do not want any delay in the effect. To achieve this, we will be changing the background-position in CSS for the hover state. First, we have to create the image files.
You can use any typeface you want, but for purposes of this tutorial, I am going to be using Heroin 07.
- From the Tools Palette select the Horizontal Type Tool. Set the font family to Heroin 07, the font size to 30pt, the anti-aliasing method to Smooth and text color to white.
- Click in the center of the lower left guide region and type “home”. The Horizontal Type Tool will automatically create a new Type Layer above your Background Layer. You may need to use the Move Tool to center the text both horizontally and vertically.
- Make sure your Smart Guides are activated by selecting View – Show – Smart Guides. Again, with the Horizontal Type Tool selected, click anywhere within the lower center guide region and type “about”. Select the Move Tool from the Tools Palette and align “about” with “home”. With your Smart Guides on, “about” will snap into place and align to “home”.
- Select the Horizontal Type Tool one last time and click anywhere within the lower right guide region and type “contact”. Using the previous method, align “contact” with “home” and “about”.
Now we are going to create the rollover images. The way the “sliding door” method works is we designate position coordinates for one image. So, we can have one file that contains both the static and rollover states. Complete the following steps to quickly create the rollover buttons.
- Select the “home” Layer. Without releasing the mouse button, drag this layer over the Create a new layer icon located at the bottom of the Layers Palette Window. This will create an exact copy of your “home” layer called “home copy”. Right click the copy and rename the layer “home rollover”.
- With the Move Tool and “home rollover” Layer selected, hold down the shift button and drag the text to the top of the document. Holding the shift key will only allow you to drag the text up or down, right or left, at a straight angle. If your Smart Guides are still activated, the text should snap into place.
- Double click the “home rollover” layer and change the color to #E32323.
- Repeat steps 1–3 for the “about” and “contact” layers.
Step 3: Slice and save your images

We are going to quickly slice our images and save them for the web. Before we complete this task, let’s take note of the dimensions of each button. This is information we will need when the coding process begins. Doing some quick math, we know that each button will be 165px wide (495 ÷ 3 = 165) and 36px tall (72 ÷ 2 = 36). Write this down for later.
- Select the Slice Tool from the Tools Palette and create three even slices of each of the buttons.
- Turn off the “Background” Layer by clicking on the Eye icon to the left of the layer name.
- Select File – Save for Web… from the Top Menu to open the Save for Web dialog box.
- Select each slice and change the settings to GIF 128 No Dither and check the Transparency option box.
- Click “Save” to open the Save Optimized As dialog box.
- Navigate to your desktop and create a New Folder and name it “www”. From the Format drop down menu, select Images Only. From the Settings drop down menu, select Default Settings. From the Slices drop down menu, select All Slices.
- Click “Save”. This will create a folder named “images” in the root folder you named “www”.
- Quit Photoshop.
Step 4: Write your XHTML mark up
Now we are going to write some valid semantic XHTML mark up for our navigational bar. Go ahead and launch your favorite code editor. Now, let’s type in the following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>Navigation Bar with Rollover Effects using Graphics Demo &amp;amp;amp;amp;raquo; Lucid Motives Blog &amp;amp;amp;amp; Tutorials</title> <link href="css/styles.css" rel="stylesheet" type="text/css" media="screen" /> </head> <body> <div id="wrap"> <ul id="nav"> <li><a class="home" href="#" title="Home">home</a></li> <li><a class="about" href="#" title="About">about</a></li> <li><a class="contact" href="#" title="Contact">contact</a></li> </ul> </div> </body> </html>
Once you have entered all of this code, save your page as “index.html” in the folder named “www”. This is your semantic mark up for the page. Notice that we did not include any images in the mark up. Your navigation is a unordered list of links enclosed within the <ul> tag. You will also notice that we have given the <ul> a unique id selector named “nav”. We have also given each of the links unique class selector names: “home”, “about” and “contact”. This is because we only want to style those particular elements and not any other <ul> or <a> tags that may appear on this page. Go ahead and test your page within Firefox. Since we haven’t written any styles yet, you should see a page that looks like this. And, if you have the Web Developers Tool installed, select Tools – Validate Local HTML and see your mark up validate according to the W3C validator.

Step 5: Write your styles
This is the final step in the tutorial. We are going to quickly style this page and add rollover functionality to our navigation bar. First, create a new document and name it “styles.css”. Place this file inside a new folder you will name “css” within the “www” directory. Now, include the following code in your stylesheet and save the file:
body {
margin:0;
padding:0;
background-color:#000;
}
a {
outline:none;
}
div#wrap {
width:495px;
margin:0 auto;
}
ul#nav {
margin-top:36px;
padding:0;
list-style:none;
width:495px;
height:36px;
}
ul#nav li {
float:left;
}
ul#nav li a.home {
display:block;
width:165px;
height:36px;
background:url(../images/nav-buttons_01.gif) no-repeat 0 -36px;
text-indent: -9999px;
}
ul#nav li a.home:hover {
background-position: 0 0;
}
ul#nav li a.about {
display:block;
width:165px;
height:36px;
background:url(../images/nav-buttons_02.gif) no-repeat 0 -36px;
text-indent: -9999px;
}
ul#nav li a.about:hover {
background-position: 0 0;
}
ul#nav li a.contact {
display:block;
width:165px;
height:36px;
background:url(../images/nav-buttons_03.gif) no-repeat 0 -36px;
text-indent: -9999px;
}
ul#nav li a.contact:hover {
background-position: 0 0;
}
Now test the “index.html” document in Firefox again and you will see your navigation bar with the rollover effect without any flicker! The CSS code will also validate according to the W3C validator! Let me quickly explain how this was achieved:
- First, remember that we kept note of the width and height of our navigational bar. You can see that reflected in how we styled the <ul> tag with an id of “nav”. We set the width to 495px and the height to 36px. Since we know that the unordered list tag is displayed with a bullet point, we’ve removed this by resetting the list-style attribute to “none”.
- Next, we know that we created a horizontal navigational bar and the unordered list will, by default, display a vertical list. We simply reset this by floating all <li> elements left.
- We also gave each link its own unique class. By doing so, we can target each class, give it a width, height and a non repeating background image. And, we also want to tell the browser where on the “x” and “y” axis to display the image (”sliding door method”). This allows us to change the position on the :hover psuedo class to display our “hover” image. As a final touch, we remove the text by setting a negative text indent that would be 9999px to the left of the browser (”image replacement method”).
And you are done. You have now created a semantically marked up navigation bar with rollover effects. You can easily tailor this method to your own website or blog design quickly and easily. Have fun with the infinite possibilities.
September 10th, 2008 at 12:25 pm
Awesome!!! I was trying to figure out how to do this last week…
Thanks!!
September 11th, 2008 at 6:17 pm
the steps is easy to practice. I like this tutorial. keep your work brother !
September 13th, 2008 at 12:13 am
Thanks for share. I like it very much !
September 19th, 2008 at 1:38 am
Hi any one give me a web link for drawing , how i draw a image on Flash , Illustrator ,
thanks
September 20th, 2008 at 6:45 pm
Cool, first it didn’t work because I put the pics in an images file, but when I put them all in the same folder, it worked. Probably a problem caused by the way my computer handels with local files.
Anyhow, great tutorial, very useful and clear.
Thank you very much,
Tim
(The Netherlands)
November 29th, 2008 at 1:48 pm
Great idea - does it work properly with IE6? See the “mail to” rollover on http://www.hazzy.net/aidan I implemented based on the above - Shows some of the other image erroneously. Works fine IE7, FF3 Safari etc.
hazzy
November 29th, 2008 at 2:27 pm
@ hazzy,
I hadn’t seen any issues with IE6 in the past. What I normally do, when confronted with possible issues in IE6, is create a conditional stylesheet for IE6. Once you have created for ie.css, decrease the height dimensions by 1 or 2 pixels and see if you still have the same issue.
I did get a chance to look over your page and coding and noticed that you are including your rollover image inside a list with only one list item. In your case, as opposed to this example, you do not need to use a list because this is only one item. I would remove the list and simply style that particular anchor class.
Let me know if this helped.
November 30th, 2008 at 6:24 am
Hi Erik,
thanks for the suggestion - I have simplified the code as per your post above and removed the list.
Sorry to report I still get the same problem I am afraid. Not sure what the issue is here (except rotten old IE6).
Should I have some white space between the two versions of the image in the GIF file? I have butted one exactly up to the other to make the GIF as small as possible. Maybe this is why I see the extra partial image?
hazzy
December 1st, 2008 at 12:24 pm
@ hazzy,
I’m sorry it still isn’t working in IE6. If I come across a solution for this issue, I will definitely post it here. Or, if anyone else has come across this issue and know of a workaround for IE6, let us know.
December 18th, 2008 at 8:55 pm
Is it possible to use this with WordPress?
December 29th, 2008 at 8:42 pm
@ Charis,
You can use this with WordPress, but I would only recommended doing so if your static pages will always remain the same and you will not be using the wp list pages function. If you will be using the wp list pages function, and still want to use custom typography, I would recommend using sIFR.
April 5th, 2009 at 2:24 pm
keep in mind, that you need to rename the 3 buttons or rename the location of the button’s name in the css file, i ended up doing everyone from the start when i found out that in the css file it was “nav_buttons” and PS saved the one i made to “nav_bars”.
but other then that, nice tutorial, if only you’d explain the parts one by one, so the NO experienced ones (like me) would be able to type along, instead of being force to copy/paste :p
April 30th, 2009 at 4:42 pm
Cool tut can you build a css nav bar with images and image drop down menu?
I’ve been trying but to no success.
May 1st, 2009 at 11:05 am
Chris,
Thanks for the kind words. You can use images in your drop down menu as well, but I wouldn’t recommend using them to replace the text itself. This method is really only for top line navigation only. But, if you are trying and having no success, are you making sure you are targeting the unordered list of a parent list item? Meaning, in your CSS, are you using something like:
ul#mainid li ul#dropdownid li a.whateverclass
Remember that CSS is all about specificity. The above line targets an unordered list list item that is the child of a parent list item… a sub menu or drop down menu.
But, for your drop downs, I would recommend adding a different background to the unordered list and then, possibly to the list items themselves to spruce them up.
Hope that helps.