Last tutorial, I showed you how to design a watercolor effect menu in Photoshop. This tutorial I will show you how to slice up the menu design (step by step) and put them together with CSS. Most of you probably know how to code a horizontal or vertical CSS list menu. Now let's take it to the next level — code an advanced (un-typical) list menu utilizing the CSS position property.
Overview
Here are the required graphics to assembe the menu (you can download from the zip).

1. Main background
Open the Photoshop file. Turn off the menu text Layer Group and save the main background as menu-bg.jpg.

2. Button graphics
Turn off the background Layer Group and leave only the menu text layers visible. Make a rectangle selection cover the "home" item, go to menu Edit > Copy Merged (Cmd + Shift + C).

Create a new file and take note of the file dimension (w x h), in my case the "home" graphic is 144 x 58px. Paste the "home" graphic in the new file. Go to menu Image > Canvas Size, adjust the image height x 2 (58 + 58 = 116px). Duplicate the home graphic layer and align it to the bottom. Erase the highlight strokes in the upper layer.

Here is how the hover effect will work. We will set the link button to 144 x 58px, when mouseover, we will shift the background image from top to bottom.

Repeat this step for the other buttons. You should have the follow graphics:

3. HTML source
When you are done with the graphics, let's start coding. Start with an un-ordered list <ul>.
- note there is an id="menu" assigned to the
<ul>tag - an unique class name assigned to each link
<a> - an empty
<span>tag (the purpose of this is to make the mouseover effect)
<ul id="menu">
<li><a href="#" class="home">Home <span></span></a></li>
<li><a href="#" class="about">About <span></span></a></li>
<li><a href="#" class="rss">RSS <span></span></a></li>
</ul>
#menu
Reset the menu to no padding, no margin, and no list-style. Specify the width and height same dimension as the menu-bg.jpg. Then attach the menu background image. The key point to remember here is set the position property to relative.
#menu {
list-style: none;
padding: 0;
margin: 0;
width: 774px;
height: 210px;
background: url(images/menu-bg.jpg) no-repeat;
position: relative;
}
#menu span
Specify the span element to display:none (so they will be invisible by default). Specify position:absolute, so we can place the mouseover GIF image on exact position.
#menu span {
display: none;
position: absolute;
}
#menu a
The key point here is the text-indent property. We specify the text-indent property with a negative value (-900%), so the text will be hidden.
#menu a {
display: block;
text-indent: -900%;
position: absolute;
outline: none;
}
#menu a:hover
When mouseover the link, we want to shift the background image from top to bottom.
#menu a:hover {
background-position: left bottom;
}
#menu a:hover span
When mouseover the link, we want the span element to display:block.
#menu a:hover span {
display: block;
}
#menu .home
Specify the width, height, and background image. Since we already specified all <a> element postition:absolute in previous step, now just say where the .home button should be by specifying the left and top property.
#menu .home {
width: 144px;
height: 58px;
background: url(images/home.gif) no-repeat;
left: 96px;
top: 73px;
}
#menu .home span
Here we are specifying the width, height, background, and position of the span element of .home (mouseover GIF image)
#menu .home span {
width: 86px;
height: 14px;
background: url(images/home-over.gif) no-repeat;
left: 28px;
top: -20px;
}
#menu .about
Copy the .home rules and rename them to .about. Now just change the width, height, background, left, and top property.
#menu .about {
width: 131px;
height: 51px;
background: url(images/about.gif) no-repeat;
left: 338px;
top: 97px;
}
#menu .about span {
width: 40px;
height: 12px;
background: url(images/about-over.gif) no-repeat;
left: 44px;
top: 54px;
}
#menu .rss
Repeat this step for .rss
#menu .rss {
width: 112px;
height: 47px;
background: url(images/rss.gif) no-repeat;
left: 588px;
top: 94px;
}
#menu .rss span {
width: 92px;
height: 20px;
background: url(images/rss-over.gif) no-repeat;
left: 26px;
top: -20px;
}
All in one:
#menu {
list-style: none;
padding: 0;
margin: 0;
width: 774px;
height: 210px;
background: url(images/menu-bg.jpg) no-repeat;
position: relative;
}
#menu span {
display: none;
position: absolute;
}
#menu a {
display: block;
text-indent: -900%;
position: absolute;
outline: none;
}
#menu a:hover {
background-position: left bottom;
}
#menu a:hover span {
display: block;
}
#menu .home {
width: 144px;
height: 58px;
background: url(images/home.gif) no-repeat;
left: 96px;
top: 73px;
}
#menu .home span {
width: 86px;
height: 14px;
background: url(images/home-over.gif) no-repeat;
left: 28px;
top: -20px;
}
#menu .about {
width: 131px;
height: 51px;
background: url(images/about.gif) no-repeat;
left: 338px;
top: 97px;
}
#menu .about span {
width: 40px;
height: 12px;
background: url(images/about-over.gif) no-repeat;
left: 44px;
top: 54px;
}
#menu .rss {
width: 112px;
height: 47px;
background: url(images/rss.gif) no-repeat;
left: 588px;
top: 94px;
}
#menu .rss span {
width: 92px;
height: 20px;
background: url(images/rss-over.gif) no-repeat;
left: 26px;
top: -20px;
}
Done
That's it. You can preview my CSS menu.
Note: there is an IE6 bug where the <span> hover effect doesn't display properly. To fix that, you can use Javascript to specify the <span> to display block on mouseover.
Great Article, I love the theme and i love how your website comes together, very creative…
Thanks…
I haven’t even finished reading the article, I am just absolutely BLOWN AWAY by your site design. Completely awesome!! As to the comment by Wendy, I think that CSS is the future of all layout not just text. I still use photoshop to export tables for my menus and rollovers. but I am currently trying to convert to CSS. why? because tables are a pain in the a**. CSS seems to allow easier placement and arranging of items without all the fuss of table alignment.
looks very interesting
I’ve got to chime in with Mike here… What’s the reasoning for adding the span tag when the same can be achieved by being directly applied to the list items themselves. I suppose its to hide the type underneath?
First: Fireworks does this better than Photoshop, and faster, too. Two: this is for personal sites because it’s not SEF. In other words, with this technique you sacrifice SEF at the expense of graphics. Sorry I can’t dig up the alternative that allows it both ways.
Pretty good, but really you need to tell me how did you do that dashed line in photoshop, or is it illustrator?
agreed…its poop
Why use the span elements at all? you can easily do the hover with a single graphic by implementing a CSS sprite. So both the normal and hover state would be one graphic and you would shift the graphic up to reveal the over state instead of using a extra unneeded span element and another graphic file. But other than that a good tutorial.
Disregard the douches who are downplaying your menu. This is a fantastic approach!!
I have to agree that this wasn’t exactly coded the easiest and most efficient way. There are quite a few things I might do differently to use less markup and CSS, but, cool idea!
Excellent article… thanks..
What font did you use for Rss. I really like that R
whos the tool who named him self “limited edition I****” (censored myself).
Also, thanks for the tip, i’m viewing this in IE7 and at first i thought it was flash when it did its transition.
Mark Story has the right idea. There is a CSS menu mouseover technique which makes the span tags unneccessary. Make one background image with both background images on it. Set the hover state for the a tag to change the background-position so that it shows the other portion of the background image. Done.
Having gotten that off my chest.. nice design.
Hey man, great tip.. Do you read your e-mail? I´ve tried sending you e-mail, but never gotten a reply back.. Please send me a note so I know how to reach you.
Cheers,
Terje
Great menu. The complicated CSS placement is amazing. Only downside is the amount of images the menu, and this site has. I prefer lightweight, fast loading, and low bandwidth consuming templates. Don’t mean to criticize your site, but 700k for a site is fairly unbelievable. There are bigger sites, but not everyone has T1. Not only that, but the bandwidth consumption is terrible.
humm… It makes me want a news template
quickly reading through your code I think there is a little simpler/shorter method that I have done before. i’ve done it on the following site – http://www.hansongardenclub.org – if someone wishes to disect my code to understand – not sure if I have a bookmark on this method…I’ll go check
i also believe the method i did worked fine in IE6 with no javascript.
copy/paste from my css
=======
#nav a:hover {
background-position: 0 -42px;
}
a.home {
display: block;
float: left;
width: 60px;
height: 42px;
background: url(“../images/nav_rollover_home.jpg”) 0 0 no-repeat;
text-decoration: none;
}
========
my html file – i took out the brackets otherwise the site converts the html
========
div id=”nav”
a href=”/” class=”home”
/div
this is all you need – i remember it working on Mac/PC multiple browsers