Professional Dark CSS Menu
I’ve provided a little screenshot below of the menu that we’re going to convert. Feel free to download the source files and you can check out a live demo if you want.

Overview
These are the only graphics you will need to create our dark menu. You can download them from the zip.

We’re going to use the container and menu backgrounds to tile horizontally for the container and menu using CSS. The menu matrix background is an image sprite we’re going to use for the links. This is only a single image with the default state on the top half and the hover state below the other half. We’re going to control how they are displayed using background positioning in CSS.
XHTML Source
Here we have a container div and another div to wrap our unordered list. Take note that we have assigned a unique id for each of the individual list elements.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Professional Dark Menu</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
</style>
</head>
<body>
<div id="container">
<div id="menuwrap">
<ul id="menu">
<li id="home"><a href="#">Home</a></li>
<li id="articles"><a href="#">Articles</a></li>
<li id="videos"><a href="#">Videos</a></li>
<li id="services"><a href="#">Services</a></li>
<li id="about"><a href="#">About</a></li>
<li id="contact"><a href="#">Contact Us</a></li>
</ul>
</div>
</div>
</body>
</html>
CSS Source
#container
You can specify any width for the container but the height must be equal to the height of containerbg.jpg. You can then tile the container background.
#container {
width:960px;
height:132px;
margin:0 auto;
background:transparent url(images/containerbg.jpg);
}
#menuwrap
Set the width to 100% so it will expand to whatever the width of the parent (#container). Height will be equal to the height of the menubg.jpg. We then apply a position:relative so we can place the #menuwrap 25 pixels from the top of the container.
#menuwrap {
width:100%;
height:63px;
position:relative;
top:25px;
background:transparent url(images/menubg.jpg) repeat-x;
}
ul#menu
Set the width and height then float the list to the right. You can easily remove float:right if you want to left align the menu. We then remove the margins, padding and remove the default bullets beside the list.
ul#menu {
width:535px;
height:59px;
float:right;
margin:0;
padding:0;
list-style-type:none;
background:transparent url(images/menubg.jpg) repeat-x;
}
ul#menu li
Now let’s float our individual list elements to the left to display the links horizontally. You could experiment and try floating them to the right.
ul#menu li {
float:left;
}
ul#menu li a
Very important to set display:block for anchor elements especially when doing image replacements because anchors are inline elements by default. The height would be the height of the menu-matrix.jpg divided by 2 which is 59 pixels. Setting the overflow to hidden will only outline the individual block of link. Then we hide the text by setting a huge negative text-indent value.
Update: Thanks to Soh Tanaka for his suggestion on optimizing the CSS for our menu. I’ve made some CSS modifications to the code below and I believe this will make our CSS easier to understand. Thank you Soh.
ul#menu li a {
display: block;
height:59px;
overflow:hidden;
text-indent:-99999px;
background:transparent url(images/menu-matrix.jpg) no-repeat;
}
ul#menu li#home a
Now we go to the fun part! We’re going to control how our image sprite (menu-matrix.jpg) will be displayed using CSS background positioning. I’ve created a guide so you can better visualize how I came up with the values.

First we’re going to style our home menu by showing only the default home graphic. We can do this by setting the horizontal and vertical position to zero. I’m writing it this way so you will have a clear idea on how the values are set. We’re also going to set the width for each of the graphic that will be shown.
ul#menu li#home a { background-position:0 0; width:82px; }
ul#menu li#home a:hover
For the hover state of the home menu, the horizontal value will be the same but we will adjust the vertical value to -59 pixels. This will position the graphic 59 pixels below starting from the top of the menu-matrix.jpg.
ul#menu li#home a:hover { background-position:0 -59px; width:82px; }
From here on it’s just a matter of calculating where you need to position the graphic. You can view the rest of the menu styles below.
Complete XHTML and CSS Source
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Professional Dark Menu</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<style type="text/css">
#container {
width:960px;
height:132px;
margin:0 auto;
background:transparent url(images/containerbg.jpg);
}
#menuwrap {
width:100%;
height:63px;
position:relative;
top:25px;
background:transparent url(images/menubg.jpg) repeat-x;
}
ul#menu {
width:535px;
height:59px;
float:right;
margin:0;
padding:0;
list-style-type:none;
background:transparent url(images/menubg.jpg) repeat-x;
}
ul#menu li {
float:left;
}
ul#menu li a {
display: block;
height:59px;
overflow:hidden;
text-indent:-99999px;
background:transparent url(images/menu-matrix.jpg) no-repeat;
}
ul#menu li#home a { background-position:0 0; width:82px; }
ul#menu li#home a:hover { background-position:0 -59px; width:82px; }
ul#menu li#articles a { background-position:-82px 0; width:89px; }
ul#menu li#articles a:hover { background-position:-82px -59px; width:89px; }
ul#menu li#videos a { background-position:-170px 0; width:87px; }
ul#menu li#videos a:hover { background-position:-170px -59px; width:87px; }
ul#menu li#services a { background-position:-256px 0; width:91px; }
ul#menu li#services a:hover { background-position:-256px -59px; width:91px; }
ul#menu li#about a { background-position:-346px 0; width:84px; }
ul#menu li#about a:hover { background-position:-346px -59px; width:84px; }
ul#menu li#contact a { background-position:-429px 0; width:102px; }
ul#menu li#contact a:hover { background-position:-429px -59px; width:102px; }
</style>
</head>
<body>
<div id="container">
<div id="menuwrap">
<ul id="menu">
<li id="home"><a href="#">Home</a></li>
<li id="articles"><a href="#">Articles</a></li>
<li id="videos"><a href="#">Videos</a></li>
<li id="services"><a href="#">Services</a></li>
<li id="about"><a href="#">About</a></li>
<li id="contact"><a href="#">Contact Us</a></li>
</ul>
</div>
</div>
</body>
</html>
I hope you will find this article helpful in creating your own optimized menu using XHTML and CSS. I want to learn from you guys so if there’s anything that you want to improve in this tutorial or anything in this blog please feel free to leave your comments below. Thank you.
Trackbacks and Pingbacks
- Create A Tabbed Content Rotator Using jQuery - Raymond Selda Blog | XHTML, CSS, PHP, MySQL, Wordpress, and all of the fun stuff under the Web!
- What Should I Write About? - Raymond Selda Blog | XHTML, CSS, PHP, CodeIgniter and Wordpress
- CSS: Professional Dark CSS Menu | Misr IT Reader
- Enlaces semanales que no he publicado (20)
- Professional Dark CSS Menu | -- KiaraNews --
- The best tutorials combining HTML,CSS,PHP and JQuery | blogfreakz.com
- CSSハックマニア その1 | Nutspress

Nicely done. May i request a tutorial for dropdown menus?
Thanks Noel. I’ll see what I can come up with dropdown menus. That’s a very nice suggestion for a future tutorial.
Hey Raymond Cool tut!
May I make a suggestion?
You can cut down the css by backpacking the menu-matrix.jpg image on the ul#menu li a, and just switching the background positioning on the others
ul#menu li a {
display: block;
height:59px;
overflow:hidden;
text-indent:-99999px;
background: url(images/menu-matrix.jpg) no-repeat;
}
ul#menu li#home a {
background-position: 0 0; width:82px;
}
ul#menu li#home a:hover {
background-positiont 0 -59px; width:82px;
}
and so on~
Thanks!
@Soh: That’s a wonderful suggestion! I’ve been used to writing CSS shorthands that I’ve neglected about individual CSS rules. I try to write optimized CSS so your suggestion definitely helped me a lot. Thank you for that. I will update my tutorial with your suggestion. Thanks for dropping by.
Really sharp! Thanks for the tut.
cool tutorial to learn the basics. thx
Very nice indeed!
Thank you.
Can you post the updated tutorial based on Soh’s recommendation? I didn’t follow what she meant (I’m new to this).
Thanks!
Melissa
can you show me how to integrate a dropdown menu to one of the menu items. thanks in advance
Awesome tutorial…thanks!
Thanks a lot for that – finally a good hint
Fantastic idea and nice code. I have a question though, what if you want to keep the sprite area that you select to stay on when going to the page selected? What needs to change in the code to handle that?
You can append a class (eg. class=”current-page”) that will display the sprite when you are in the page selected. Hope this helps.
Well I tried your suggestion the best I could and couldn’t get it to work correctly. I have to admit that my coding skills aren’t the best. Can you post what and where things would go? I really like how slick this is! Thank you in advance!
Sure! This can be a little tricky because the menu uses background positioning for the sprites but I know you can pull it off.
Here’s what you do. For eg. if you want to highlight the About menu if you’re currently on the about page.
Step 1: Copy the code that makes the hover action work for the About but this time you’re going to target an anchor tag that has a class=”current”. Same CSS but different target.
ul#menu li#about a.current { background-position:-346px -59px; width:84px; }Step 2: You then append class=”current” inside the anchor tag that you’re currently in which is in our case the About section.
class="current"Step 3: Refresh and you’re About menu will be highlighted.
Hope this helps. Good luck.
I tried out the code you suggested Raymond and it worked great for the first sprite (home), but the others won’t switch. I’m not sure what I’m doing wrong, see code below. Sorry for being such a pain. I can zip up everything and email it to you if you’d like to see what I’m working on. I’d be interested in your take on what I’m doing. Again, thanks for all the help!
index.html
Home
Lodging
Shopping
Recreation
Dining
Sweets_and_Treats
Groceries
Arts
Antiques
Real_Estate
Services
Events
Gallery
Links
Contact_Us
menu.css
/*======= top menu =======*/
.container1 {
width:766px;
height:32px;
margin:0 auto;
}
.menuwrap1 {
width:100%;
height:32px;
position:relative;
background:transparent url(images/menu_bckgrnd.jpg) repeat-x;
}
ul#menu {
width:756px;
height:32px;
float: left;
margin:0;
padding:0;
padding-left: 10px;
list-style-type:none;
background:transparent url(images/menu_bckgrnd.jpg) repeat-x;
}
ul#menu li {
float:left;
}
ul#menu li a {
display: block;
height:32px;
overflow:hidden;
text-indent:-99999px;
background:transparent url(images/menu_top_matrix.jpg) no-repeat;
}
ul#menu li#home a { background-position:0 0; width:71px; }
ul#menu li#home a:hover { background-position:0 -32px; width:71px; }
ul#menu li#home a.current { background-position:0 -32px; width:71px; }
ul#menu li#lodging a { background-position:-71px 0; width:84px; }
ul#menu li#lodging a:hover { background-position:-71px -32px; width:84px; }
ul#menu li#lodging a:current { background-position:-71px -32px; width:84px; }
ul#menu li#shopping a { background-position:-155px 0; width:92px; }
ul#menu li#shopping a:hover { background-position:-155px -32px; width:92px; }
ul#menu li#shopping a:current { background-position:-155px -32px; width:92px; }
ul#menu li#recreation a { background-position:-247px 0; width:102px; }
ul#menu li#recreation a:hover { background-position:-247px -32px; width:102px; }
ul#menu li#recreation a:current { background-position:-247px -32px; width:102px; }
ul#menu li#dining a { background-position:-349px 0; width:73px; }
ul#menu li#dining a:hover { background-position:-349px -32px; width:73px; }
ul#menu li#dining a:current { background-position:-349px -32px; width:73px; }
ul#menu li#sweets a { background-position:-422px 0; width:140px; }
ul#menu li#sweets a:hover { background-position:-422px -32px; width:140px; }
ul#menu li#sweets a:current { background-position:-422px -32px; width:140px; }
ul#menu li#groceries a { background-position:-562px 0; width:95px; }
ul#menu li#groceries a:hover { background-position:-562px -32px; width:95px; }
ul#menu li#groceries a:current { background-position:-562px -32px; width:95px; }
ul#menu li#arts a { background-position:-657px 0; width:87px; }
ul#menu li#arts a:hover { background-position:-657px -32px; width:87px; }
ul#menu li#arts a:current { background-position:-657px -32px; width:87px; }
/*======= bottom menu =======*/
.container2 {
width:766px;
height:32px;
margin:0 auto;
}
.menuwrap2 {
width:100%;
height:32px;
position:relative;
background:transparent url(images/menu_bckgrnd.jpg) repeat-x;
}
ul#menu2 {
width:686px;
height:32px;
float: left;
margin:0;
padding:0;
padding-left: 80px;
list-style-type:none;
background:transparent url(images/menu_bckgrnd.jpg) repeat-x;
}
ul#menu2 li {
float:left;
}
ul#menu2 li a {
display: block;
height:32px;
overflow:hidden;
text-indent:-99999px;
background:transparent url(images/menu_bottom_matrix.jpg) no-repeat;
}
ul#menu2 li#antiques a { background-position:0 0; width:89px; }
ul#menu2 li#antiques a:hover { background-position:0 -32px; width:89px; }
ul#menu2 li#antiques a:current { background-position:0 -32px; width:89px; }
ul#menu2 li#realestate a { background-position:-89px 0; width:105px; }
ul#menu2 li#realestate a:hover { background-position:-89px -32px; width:105px; }
ul#menu2 li#realestate a:current { background-position:-89px -32px; width:105px; }
ul#menu2 li#services a { background-position:-194px 0; width:88px; }
ul#menu2 li#services a:hover { background-position:-194px -32px; width:88px; }
ul#menu2 li#services a:current { background-position:-194px -32px; width:88px; }
ul#menu2 li#events a { background-position:-282px 0; width:75px; }
ul#menu2 li#events a:hover { background-position:-282px -32px; width:75px; }
ul#menu2 li#events a:current { background-position:-282px -32px; width:75px; }
ul#menu2 li#gallery a { background-position:-357px 0; width:79px; }
ul#menu2 li#gallery a:hover { background-position:-357px -32px; width:79px; }
ul#menu2 li#gallery a:current { background-position:-357px -32px; width:79px; }
ul#menu2 li#links a { background-position:-436px 0; width:66px; }
ul#menu2 li#links a:hover { background-position:-436px -32px; width:66px; }
ul#menu2 li#links a:current { background-position:-436px -32px; width:66px; }
ul#menu2 li#contact a { background-position:-502px 0; width:102px; }
ul#menu2 li#contact a:hover { background-position:-502px -32px; width:102px; }
ul#menu2 li#contact a:current { background-position:-502px -32px; width:102px; }