Drop down menus are among the coolest things on the web. Beside that they are also very good for creating navigations that contain many elements. The main problems of creating drop down menus lies in the Internet Explorer’s inappropriate way of displaying :hover pseudo class (not recognized anywhere except in A tag), and the problem in calculating the z-index when an element is positioned absolutely inside a relatively positioned element.

How to start?
To better understand this article, you could read the Suckerfish dropdown article on A List Apart. You did already? Then please proceed. We will create a horizontal menu with a submenu on “Projects” and two submenus (Older projects and Active projects). Here is the code.
<ul id="menu">
<li><a href="#" title="Homepage" class="selected">Homepage</a></li>
<li><a href="#" title="About us">About us</a></li>
<li><a href="#" title="Projects">Projects</a>
<ul>
<li><a href="#" title="Older projects">Older projects</a>
<ul>
<li><a href="#" title="2003 projects">2003 projects</a></li>
<li><a href="#" title="2004 projects">2004 projects</a></li>
<li><a href="#" title="2005 projects">2005 projects</a></li>
</ul>
</li>
<li><a href="#" title="Active projects">Active projects</a>
<ul>
<li><a href="#" title="Leaf industries">Leaf industries</a></li>
<li><a href="#" title="Omnicron">Omnicron</a></li>
<li><a href="#" title="Unkown.com">Unkown.com</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#" title="Contact">Contact</a></li>
</ul>
Let’s style up the elements, shall we? We will remove the bullets and remove any padding and margin we could have from the first level and second level menu (#menu, #menu ul { ... }). Now we will style up first level list items. We will use a float method and we will position the elements relatively. To create a “please click here on this button look” we will use line-height: 4.5em; (to create a 45px high button) and width: 10em;.
#menu, #menu ul {
list-style:none;
padding:0;
margin:0;
}
#menu li {
float:left;
position:relative;
line-height: 4.5em;
width: 10em;
}
Now, we are going to position the second level navigation lists. As we said, we will position them absolutely inside their list items. Because the first level list has the ID #menu if we want to define a style for the next level we must use #menu li ul which actually says: “This refers to all the second level UL’s inside first levelLI’s, inside UL’s with ID #menu” (we could also define it with ul#menu li ul, but this way we keep it a bit shorther).
Okay, now this is a tricky part which had me thinking a lot. We could position the second level navigation with top and left, and this will work just fine in Firefox. Because of IE and its problem of calculating the correct z-index position, we will use the margin-top and margin-left instead (I will show you why is this very important later in this article). So we will position the second level navigation a little above the first level (as shown in the picture before), and the third level little above the second level (it looks just cool to me :).
We don’t want to show the second level navigation until the mouse goes over the navigation element that has the submenu (Projects). So we should use the display:none; here. Because we cannot see the second level, there is no chance we will see the third, right?
#menu li ul {
position:absolute;
margin-top:-1em;
margin-left:.5em;
display:none;
}
#menu ul li ul {
margin-top:-3em;
margin-left:7em;
}
Styling the links
For start, we have to display links as blocks so the whole button area would become a link. With #menu a { ... } we will define the linked elements. Border-right is here to move apart the first level menu elements. Why don’t use the margin-right:1px; instead, you ask? Well, there is no exact reason. If we use margins to move apart the elements, we won’t see the problem until we would like to remove the elements in the second and every next level of navigation. If we use margin-bottom:1px; to remove these elements, the elements will disappear because we would have a gap between them. While using borders instead of margin, the gap isn’t there, because the border is the part of an element.
Our menu elements will have redefined background, color, text-decoration and padding. Because we used line-height to define height of the buttons, we do not have to define top and bottom padding, but we have to define it for left and right.
We will set up slightly different styles for the first and second navigation levels to make a difference between them. To the second level menu elements we will add right, left and bottom borders, and a border to the <ul> tag. This way we don’t have to overlap the elements by 1px on top.
#menu a {
display:block;
border-right:1px solid #fff;
background:#E0F574;
color:#3B3B3B;
text-decoration:none;
padding:0 10px;
}
#menu a:hover {
background-color:#5798B4;
color:#fff;
}
#menu ul {
border-top:1px solid #fff;
}
#menu ul a {
border-right:none;
border-right:1px solid #fff;
border-bottom:1px solid #fff;
border-left:1px solid #fff;
background:#AEC245;
}
The second level isn’t visible by default, because we hided it with display:none;. Now, we want to display a second level, but not the third. If we simply add #menu li:hover ul { display:block; } we would display both the second and the third level because this is inherited. So, we will add #menu li:hover ul ul { display:none; } to hide the third level. If you wish to add a fourth level of navigation, you can simply do that by adding one more UL to the CSS code.
/* SHOW SUBMENU 1 */
#menu li:hover ul, #menu li.over ul {
display:block;
}
#menu li:hover ul ul, #menu li.over ul ul {
display:none;
}
/* SHOW SUBMENU 2 */
#menu ul li:hover ul, #menu ul li.over ul {
display:block;
}
JavaScript to the rescue
You surely noticed the second selector #menu li.over ul and wondering why is this here. If you have read the ALA article about drop down menus you already know that. As you can remember, Internet Explorer doesn’t recognize the :hover pseudo class anywhere but on the links. As we added a :hover pseudo class to the list item with li:hover, IE won’t display the submenus. We can use a JavaScript from A List Apart as this will work - but for displaying the second level only.
Thanks to my friend Miha Hribar, we now have the solution to that problem. Miha resolved the problem by writing a nice snippet of JavaScript code that resolves the problem of not displaying the third level submenu and so on. Here is what Miha says:
“The js snippet is very simple in its self. It finds the navigation by using the document.getElementById and the loops though all the child li tags (perhaps child tags is not the best analogy here, as the loop goes through all the li tags under the current ul node, wich in fact means all decendants of the parent). For every li tag it searches for a child ul tag, wich means that the list element has a sublist (or in our case a submenu). So when and if we find it, all we need to do is append a javascript function to the onmouseover and onmouseout events, wich just sets the inline style of the sublist to block when hovered over and none (thus hidding it from plain sight) when the mouse leaves the hover area.” Thanks again Miha!
Z-index and height problem in Internet Explorer
Earlier I mentioned the z-index problem in Internet Explorer. The problem appears when you want to position an element absolutely inside a relatively positioned element (our first level menu elements are floated left and positioned relatively, and our second and third levels unordered lists are positioned absolutely). Take a look at our next picture.

To prevent that from happening, first we positioned elements with margins instead of top and left positioning. The next thing we would do is use the conditional comments for IE. Because the problem pops up in the list-items elements, we will use static instead of relative position. The problem is solved.
<!--[if IE]>
<style type="text/css">
#menu li {
position:static;
}
</style>
<![endif]-->
To resolve the height calculation problem in IE we have to use this piece of code in our CSS file.
/* Fix IE. Hide from IE Mac \*/
* html ul li { float: left; height: 1%; }
* html ul li a { height: 1%; }
/* End */
The example
Further reading
z-index attribute at MSDN
Effect of z-index value to relatively positioned and absolutely positioned blocks
IE’s relative z-index calculation
Share and Enjoy
The first thing for a good website developed for business purpose is web design. Nowadays there are many new technologies being offered by the providers, ip phones is one of them. The website developed should be launched by a site which provides proper website hosting. But you must be careful and should take few measures like online backup. If someone wants to develop his/her own website, then they should first go for web development courses. After developing the website, it should be launched on the web hosting server with the help of webhosting websites.













Thursday, October 12, 2006 @ 17:59
Well done, the final result is very nice.
Tuesday, December 26, 2006 @ 8:15
woo… it is beauty.
Tuesday, January 16, 2007 @ 11:34
@Marko: Thanks for the comment. I love your site (tough I am way to slow on commenting this post, shame on me :)
@Travis: Tnx.
Thursday, March 22, 2007 @ 20:40
This is really good and I understand most if it, but when I’ve tried it in IE I get any text on the background bleeding through the menus. I’ve seen this before and I wonder if you can tell me why it happens?
Friday, March 23, 2007 @ 20:00
Simon, I must admit that I don’t understand the very nature of your problem. Could you spare me a link to it? Did you put the conditional comment for IE as I suggested in the end of the article?
Tuesday, March 27, 2007 @ 13:20
I have worked out my problem. I needed to set the z-index on the page container to lower than the menu’s, otherwise the text in the container was visible though the menu! In other words, my mistake!
Now I am trying to change the menu so the second level is also shown as a drop down (rather than horizontal) menu.
Keep up the great work…
Wednesday, March 28, 2007 @ 10:37
I like the final result very much but I am afraid that the javascript part doesn’t work in Safari.
Many thanks anyway, keep it up, if find a solution I will let you know.
Thursday, March 29, 2007 @ 11:35
Simon: I am glad this worked out for you.
Thys: I didn’t have the opportunity to test the JS in Safari. If you or anyone else should find a solution to the problem please let us all know :)
P.S.
I like your site and your motion-graphics work you’ve done!
Saturday, March 31, 2007 @ 5:26
Splendid display of code work…
Happy validating with what you’ve done here, I’m a new pupil to the world of HTML & CSS. This site helped me get through an all nighter, thanks.
MrFlick
Thursday, April 05, 2007 @ 15:30
The site looks great ! Thanks for all your help ( past, present and future !)
Saturday, April 07, 2007 @ 21:36
Thanks morganusvitus, I will try to write more interesting articles.
Wednesday, July 18, 2007 @ 19:23
This helped me a lot.
One problem tho.
I’m using images as each button in the drop-down menu, and i get gaps of about 3 pixels in between the buttons. i tried setting the font to 2pt and lineheight to .4, which works for other divs when i have gaps, but no luck. how do i avoid the gaps?
Thursday, July 19, 2007 @ 8:23
Hi Alfredo. Could you give us the link to your problem?
Thursday, July 19, 2007 @ 22:26
here is a section of the code with one button, as i don’t have any of it online yet. I’m pretty new to coding, if you find any other errors please do tell! :)
Also note that i’m using safari, that’s where i get the gaps. i’ve also tried giving the style a very small font size and line height, which has worked for arranging div’s, but it doesn’t work for this.
Also, i used a lot of reference to suckerfish drop-down menus, for compatibility, and copied the javascript hack for IE.
Thanks in advance! love your site!
body {
}
#nav, #nav ul {
padding: 0;
margin: 0;
list-style: none;
display: block;
height: 27px;
width: 157px;
float: left;
}
#nav li ul {
position: absolute;
height: 27 px;
width: 157px;
left: -999em;
}
#nav li:hover ul, #nav li.sfhover ul { /* lists nested under hovered list items */
left: auto;
}
Thursday, July 19, 2007 @ 22:36
oops… duh, there are tags.
i uploaded with yousendit.com: http://www.yousendit.com/transfer.php?action=check_download&ufid=3425FC18786CA983&key=4f9d2bb8688539f7a1688a39a377a2ac8b5f35b4
Wednesday, November 07, 2007 @ 18:46
Hi I am able to implement. I got correct display in IE 6.0. But In IE 7.0, firefox, opera its diplaying horizontally. Can you please suggest me to fix this problem. Thanks!
Thursday, November 08, 2007 @ 19:36
Sree, could you give us a link to it, and a screenshot maybe? You could send it to e-mail (look the about page for it :).
Saturday, November 10, 2007 @ 1:33
Thanks for the response… Please send me a test mail to sreekanth.mca@gmail.com. I haven’t find the mail id of you. Once again thanks for response and i hope my problem is going to be slove in soon with your help.
Friday, November 30, 2007 @ 15:37
I don’t know if I am missing something, but where might I find the javascript snippet that Miha wrote?
Friday, November 30, 2007 @ 16:22
Nevermind, I found it on someone else’s blog, from 2004…
CSS Drive
Saturday, December 01, 2007 @ 11:57
Anthony, the script can be found here. It is called within the example, and it works really fine :)
Sunday, December 16, 2007 @ 7:06
Sree, I was having the same trouble with the menu in IE 7. After adding this bit of code, the problem was resolved:
#menu li ul li {
clear:left;
}
I hope that helps. Thanks for the excellent website, emanuel.
Monday, February 18, 2008 @ 19:55
Thank you very much Emanuel and thanks to Miha Hribar too.
I´ve been really obsessed by this question in two last days.
I wanted to make a third level in a dropdown menu for IE-Mac from the suckerfish article, but it was imposible.
I´m very glad to find your page. The javascript code works perfectly and easily.
Now there is a problem in Safari 2.0. It isn´t recognized the styles for the a:hover (in submenu and subsubmenu) items. Do you know any solution about this?
Anyway, I want to end thanking you both again. Your discovery have been very important to me.
Thursday, July 03, 2008 @ 9:53
Great CSS javascript tutorial,thanks for sharing you ideas.