CSS horizontal menu with dropdowns
I was looking for a simple tutorial for a css-only horizontal dropdown menu earlier this week, aimed at a css beginner. And I couldn’t find one, so here’s how to build this menu….
I’m going to do this in two stages:
Creating a simple horizontal menu – no dropdown
Before we get into the dropdowns, let’s just sort the horizontal menu bit. Let’s start with the html markup, which is a standard unordered list. Let’s have four menu items:
<ul id="horiznav"> <li><a href="#">Item 1</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 3</a></li> <li><a href="#">Item 4</a></li> </ul>
Nothing too exciting there. Now let’s have a look at the css:
ul#horiznav{
margin:0;
padding:0;/*set both to zero to remove browser inconsistencies*/
list-style-type:none;/*get rid of bullet points*/
height:32px/*just to avoid some possible float issues*/
}
#horiznav li{
float:left;/*float the li element so the menu's horizontal...*/
width:150px/*...and set the width*/
}
#horiznav li a{
display:block;/*make the link a block element...*/
width:150px;/*...with a fixed width...*/
line-height:30px;/*...and set the line-height to vertically centre the text*/
text-align:center;/*horizontally centre the text...*/
color:white;/*...colour it white...*/
text-decoration:none;/*...and remove the default underline*/
background-color:#EA9531;/*give the link an orange background...*/
border:1px solid white/*...and a white border...*/
}
#horiznav li a:hover{
color:#333333/*change the text colour on :hover*/
}
See comments in the css for an explanation. The key thing that’s making the menu horizontal is floating the <li> element. This code gives us this:
Adding the drop down
Now we’ll add the drop down. The dropdown elements are included as additional <ul> elements nested within the appropriate <li> element. Like this:
<ul id="horiznav">
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a>
<ul>
<li><a href="#">Item 2.1</a></li>
<li><a href="#">Item 2.2</a></li>
</ul>
</li>
<li><a href="#">Item 3</a>
<ul>
<li><a href="#">Item 3.1</a></li>
<li><a href="#">Item 3.2</a></li>
<li><a href="#">Item 3.3</a></li>
</ul>
</li>
<li><a href="#">Item 4</a>
<ul>
<li><a href="#">Item 4.1</a></li>
<li><a href="#">Item 4.2</a></li>
<li><a href="#">Item 4.3</a></li>
</ul>
</li>
</ul>
Right, now for the css. We need to make a few additions – marked in red:
ul#horiznav, #horiznav ul{/*remove the bullets from the dropdown ul as well*/ margin:0; padding:0; list-style-type:none; height:32px } #horiznav li{ float:left; width:152px; position:relative/*set position:relative as the start point for absolutely positioning the dropdown*/ } #horiznav li a{ display:block; width:150px; line-height:30px; text-align:center; color:white; text-decoration:none; background-color:#EA9531; border:1px solid white } #horiznav li a:hover{ color:#333333 } #horiznav li ul{ display:none;/*hide the dropdown*/ position:absolute;/*position it absolutely..*/ left:0;/*...align the left edge with the left edge of the parent li...*/ top:32px/*...and 32px down from the top - 30px height + 2px for the border*/ } #horiznav li:hover ul { display:block/*display the ul when the parent li is hovered*/ } #horiznav li ul a{ background-color:#FFB33B/*give the dropdown a different background colour*/ }
See the comments in the code for explanations. A surprisingly small amount of css, really. The dropdowns are normally hidden, and appear when the parent <li> is hovered. So this gives us (same as at the top of the page):
You’ll see that the use of absolute positioning makes the dropdown appear on top of anything else on the page – which is what we want. And this works fine in pretty much every browser in popular use today. Specifically I’ve tested in IE7, IE8, FF3, Chrome, Opera9, Opera 10, Safari4. You’ll spot there’s something missing. No prizes for guessing what browser causes a little extra difficulty…
Dealing with the dropdown in IE6
IE6 doesn’t support :hover, except on <a> elements. So without a bit of extra code, our nice dropdown won’t work at all in IE6. Fortunately, there’s a solution called csshover, which you’ll find here along with instructions on how to use it. I’ve personally found version 2 of this software to be the most reliable.
Adding animation with jQuery
To add some animation – fades, slides etc – have a look at my jQuery plugin here, which allows more sophisticated animation for javascript users while preserving the css approach for those without.