Skip to page content or Skip to Accesskey List.

Work

Main Page Content

How To Make A Simple Css Dropdown Menu

Rated 3.45 (Ratings: 14)

Want more?

  • More articles in Code
 
Picture of trfc791

Grace Teng

Member info

User since: 15 Sep 2002

Articles written: 1

You've seen those cool Javascript menus that drop down subitems when you move your mouse over them or click on them. One day, in a fit of boredom, I set out to achieve the same effect via CSS. Unfortunately, this only works on browsers that can render hover styles on arbitrary elements, so Netscape and Mozilla users, crow over your IE counterparts for once. It will not work on Opera either. Not tested in Konqueror. Ironically, it looks perfectly fine in Lynx.

Why should I want to have a CSS menu?

There's no real reason why you should use a CSS menu instead of a Javascript menu. In fact, I/you think I'm crazy to have tried in the first place. On the other hand, how many Javascript menus work across all browsers? How will the navigation menu turn out in Lynx? I checked The Javascript Source and the first four dropdown menus I came across were IE only. I would think it is actually simpler to write one in CSS, but the fact that it cannot display in IE negates all the advantages of using CSS. Still, it never hurts to try this. Hopefully, by the time you understand this, IE will have improved their lousy rendering engine.

OK, so how does it work?

The first idea that comes to mind is nested divs. That's what I thought of too. But after surfing around, I came upon Eric Meyer's Pure CSS Menus example. It uses nested lists, which has several advantages over nested divs, both to the end user and the programmer.

The end user, if using Internet Explorer, Opera, or another browser that cannot render hover styles on arbitrary elements, will only be able to see the top level elements which may or may not be links. If they are links, make the page it links to show the items on the submenu as well. If they are not links, tell the user to bash his/her head for not using a better browser or do some browser detection, which will not be covered here. If the user is using a browser that doesn't support CSS, the menu will come out as a bunch of nested lists. Of course, Mozilla and Netscape will display it as a dropdown menu. For the programmer, there is no need to hunt through piles of nested divs any more. The lists and list items clearly show which items are submenu headings and which are navigation items.

Give me the code!

The whole idea is based on these lines of CSS:

li ul {

display: none;

}

li:hover > ul {

display: block;

}

If you can't figure out what it means, it just means that a <ul> nested inside an <li> tag should not be displayed, and when the user moves his cursor over the list item, the nested list should appear. The code for the nested list is:

<ul>

<li><a href="#">Heading 1</a></li>

<li><a href="#">Heading 2</a>

<ul>

<li><a href="#">Subitem 1</a></li>

<li><a href="#">Subitem 2</a></li>

<li><a href="#">Subitem 3</a></li>

</ul>

</li>

<li><a href="#">Heading 3</a>

<ul>

<li><a href="#">Subitem 4</a></li>

<li><a href="#">Subitem 5</a></li>

<li><a href="#">Subitem 6</a></li>

</ul>

</li>

</ul>

Throw in a little formatting and voila! You have your own CSS dropdown menu!

The non-Mozilla-and-Netscape-but-not-Lynx users (well I'm sure you know which group of people I'm referring to) will see only Heading 1, Heading 2 and Heading 3. Make sure the pages that Heading 2 and Heading 3 link to also have links to Subitem 1 - 6, for the sake of those users who cannot see and use the dropdown menu.

Don't stop there!

Unless you want every single list in your page to work this way, the CSS still needs more refining. You don't want your nested to-do list to play hide and seek with you. To prevent this, use classes or IDs. You can give each menu item a class, but that would be ridiculous if you have 100 menu items. Much simpler to use an ID on the base <ul>. Now, the CSS looks like this:

ul#nav li ul {

display: none;

}

ul#nav li:hover > ul {

display: block;

}

Subsequently, just add id="nav" on your base <ul>.

Example?

My own trial turned out fine for Mozilla but came out utterly wrecked in IE, which came as no surprise to me. Being my work, it is not worth a plug here. Inigio Surguy has a cool example, but he uses nested divs instead. I've not checked that out in IE, but looking at the source, it is probably wrecked in IE too. I mean, it will look good but will be useless. Be sure to check out his alternate stylesheet if you are using Mozilla or Netscape 6. Also, have a look at Eric Meyer's Pure CSS Menus.

What now?

You might want to try nested lists inside nested lists inside nested lists, or something along those lines. Don't forget to add in some formatting. You should also look at CSS Edge for more interesting things you can do with CSS, and in particular, these CSS popups look good.

A Final Note

I would like Microsoft more if they produced more decent software, especially web browsers. However, please do not regard this as some anti-Microsoft propoganda or something of that sort, because it is not. It just so happens that this menu does not work in what is supposedly the world's most popular browser. No flaming please.

trfc791 is a person often bored to death with school and homework, and can often be found in cyberspace under the name trfc791. But then you knew that already. Unlike most of my friends, I can program (What else would I be doing at evolt?) and program very badly too. If you're here, you probably don't know me because all the people I know who know me would never come to evolt and I suggest you don't continue to know me. My site (free plug :P) can be found at http://trfc791.f2o.org/. When I am on IRC, I am usually on #f2o and on rare occasions, on #evolt.

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.