Web Design
Drop-Down Menus using CSS
Drop-down menus (sometimes called pop-up or pull-down menus) are popular on web sites that have a lot of pages for their ability to save space: dozens of links can be squeezed into a narrow horizontal (or in rare cases vertical) space that would normally contain only five or six. Unfortunately, drop-downs have their disadvantages too: most javascript-based menus tend to be complicated, hard to edit and won't function on browsers with javascript disabled; those that use only CSS are much simpler, but they won't work when viewed with Explorer for Windows (which, unfortunately is the most popular browser on the planet. Did I mention the Explorer sucks?). Fortunately there is solution; the folks at HTML Dog have come up with an ingenious CSS-based method that utilizes a simple javascript hack to trick Explorer into behaving. The finished result will look like this:
Procedure
- Create a menu of links. The key here is to make each main link its own separate list <ul>. Sub-menus (those that will drop down) should also be separate lists, placed inside the list item (before the closing </li> tag) for each of the main categories. You can use the following markup to save time:
<div id="container"> <ul id="nav"> <li><a href="#">Baseball</a> <ul> <li><a href="#">Yankees</a></li> <li><a href="#">Twins</a></li> <li><a href="#">Mets</a></li> </ul> </li> <li><a href="#">Football</a> <ul> <li><a href="#">Giants</a></li> <li><a href="#">Vikings</a></li> <li><a href="#">Jets</a></li> <li><a href="#">Steelers</a></li> <li><a href="#">Lions</a></li> </ul> </li> <li><a href="#">Hockey</a> <ul> <li><a href="#">Rangers</a></li> <li><a href="#">Wild</a></li> <li><a href="#">Islanders</a></li> <li><a href="#">Stars</a></li> </ul> </li> </ul> </div> - Now we add some basic structure with CSS:
The width of course can be changed according to your design.
<style type="text/css"> <!-- #nav, #nav ul { float:left; padding: 0; margin: 0; list-style: none; } #nav a { display: block; width: 140px; line-height: 2em; padding-left: 10px; } #nav li { float: left; width: 150px; //this line is needed to keep it from breaking in Opera } --> </style> - Next we will add some visual styling (colors, fonts, etc.). These of course are not set in stone; in fact you should customize the look of your menus according to your design:
Make sure you set the font size in the container's style, not the list's style. If you use ems or percentages for font size and put it in the <ul> style, every sublist will have text that is that much smaller (or larger). For example, if you set the font size to .8em, each sublist will display the text 80% smaller than its parent list.
#container { font-family: Arial, Helvetica, serif; font-size: .9em; font-weight: bold; } #nav, #nav ul { float:left; padding: 0; margin: 0; list-style: none; background-color:#174086; } #nav a { display: block; width: 140px; line-height: 2em; padding-left: 10px; color: #FFF; border-bottom: 1px solid #174086; text-decoration: none; } #nav li { float: left; width: 150px; //this line is needed to keep it from breaking in Opera } #nav li a:hover {
background-color:#39F;
} #nav li ul { background-color:#36C; } - Now we need to hide the drop-down lists. In the past it was common to use display:none, but that has caused problems with accessibility. A better option is to shove the menus way off screen by using the margin property. Add these styles:
The first rule hides all lists that are contained within other lists. The #nav li:hover rule causes the sub-menu lists to reappear when we mouse-over it's parent list item. Try it; if you're using any browser other than IE, it should work.
#nav li ul { background-color:#36C; position: absolute; width: 150px; left: -999em; } #nav li:hover {
position:static;
} #nav li:hover ul { left: auto; } - Unfortunately, older versions of Explorer does not recognize pseudo-styles for tags other than <a> tag so we need to add a bit of javascript to trick IE into seeing our hover command. In the head portion of your document, after the closing style tag add the following code:
<script type="text/javascript"> <!-- sfHover = function() { var myElement = document.getElementById("nav").getElementsByTagName("li"); for (var i=0; i<myElement.length; i++) { myElement[i].onmouseover=function() { this.className+=" dropHover"; } myElement[i].onmouseout=function() { this.className=this.className.replace(new RegExp(" dropHover\\b"), ""); } } } if (window.attachEvent) window.attachEvent("onload", dropHover); --> </script>This creates a function that applies a class style called "sfhover" to all of the list items when they are moused-over, causing the submenus to appear, and removes the class style when moused-out.
- But to actually apply this function we need to make two small additions to our styles:
#nav li:hover, #nav li.dropHover { position:static } #nav li:hover ul, #nav li.dropHover ul { left: auto; }
- Important: since the menu uses floats, make sure you add a clear:left to whatever element follows the menu in the markup.
- Want to add another tier of menus (sub-sub menus that open to the side)? Check out the "Son of Suckerfish" tutorial at HTMLDog.com.