Substituting CSS-based techniques for old-style graphic rollovers and DHTML menus is one of the most effective web site optimization techniques available. Graphic rollovers use “on” and “off” graphics to create rollover effects, with and without JavaScript. DHTML menus create nested menu structures with JavaScript, some of it complex. With the widespread adoption of CSS2-aware browsers, there is a better choice: CSS-based techniques. Substituting list-based markup, CSS2 to style, and an optional dash of JavaScript makes for fast, small, and accessible CSS menus.
CSS2 Rollover Menus
For simple rollover menus you can substitute lists styled with CSS2. Our home page uses this technique to create rollover menus. The key is to markup lists as lists, not kludge them with breaks and paragraphs. Here is a sample code snippet:
#m{margin:0 25px;padding:0;list-style:none; border-top:1px solid #c0afcf;} #m a:link,#m a:visited{display:block;margin:1px 0; padding:3px 0;background:#9966ad; color:#fff;text-decoration:none;text-indent:6px; font-weight:bold;width:150px} #m a:hover{background:#dcdcdc;font-weight:bold;color:#9966ad} ... <div id="s"> <ul id="m"> <li><a href="/about/" title="about us.">About</a></li> <li><a href="/services" title="services.">Services</a></li> ... </ul> </div>
Note how we change the links into block-level elements, and reverse the background and text on :hover. This technique works in all version 5 browsers, including IE 5.x for the Mac. Done with graphics and JavaScript these menus would require two HTTP requests for each menu item (unless you use the one graphic rollover method).
Descriptive lists can also be morphed into headlines and decks (flush left) with CSS (dd{text-indent:0;}
} to style the headline (dt{font-weight:bold;}
.
CSS2 + JavaScript Drop-down Menus
You can take these menus one step further and add submenus to the mix. By nesting your unordered lists, and hiding the secondary menus, you can turn them back on with the :hover pseudoclass as demonstrated in the so-called “Suckerfish Dropdowns.”
li ul { display:none; position:absolute; top:1em; left:0; } ... li:hover ul {display: block;} ... <div id="nav"> <ul> <li><a href="/">Home</a></li> <li><a href="/sitemap/">Sitemap</a></li> <li><a href="/speed/">Speed Up Your Site</a> <ul> <li><a href="/speed/1/">Chapter 1</a></li> <li><a href="/speed/2/">Chapter 2</a></li> <li><a href="/speed/3/">Chapter 3</a></li> </ul> </li> </ul> </div>
Or can you? Unfortunately, IE 5 or greater does not recognize the :hover pseudoclass on elements other than the humble link. There are two ways around this, you can add another class to the element dynamically to signify that it is in the hover state, or you can attach the :hover event to all elements with a behavior. Patrick Griffiths and Dan Webb took the first approach, Peter Nederlof and Eric Meyer took the second. To add an “over” class to a hovered list item, add this selector to your display:block; rule:
li:hover ul, li.over ul{display:block;}
Now you just need to cycle through the list elements to see if one has been moused over and dynamically add a class of “over
.” Griffiths and Webb show us how in their Suckerfish Dropdowns tutorial. This version has the advantage of working with IE 5.x Mac.
CSS2 Drop-down Menus
The alternative approach is to fix IE’s recalcitrance with a behavior, which is nothing more than some JScript saved to a “.htc” file. Peter Nederlof has done just that. His “whatever:hover” attaches :hover behavior to any element, making CSS-only drop-downs possible. Eric Meyer demonstrates how to do pure CSS-based drop-down menus in his new book More Eric Meyer on CSS in Chapter 6: “CSS-Driven Drop-Down Menus.”
The two keys are the body call to the behavior, and strategic classes in the lists. Meyer’s menus look something like this:
body{color:#000;background:#fff;behavior:url(csshover.htc);} /* WinIE hover Behavior Fix */ div#nav{float:left;width:7em;margin:-1px 0 0 Â1px;background:#fdd;} div#nav ul{margin:0;padding:0;width:7em;background:white;border:1px solid #aaa;} div#nav li{position:relative;list-style:none;margin:0;border-bottom:1px solid #ccc;} div#nav li:hover{background:#ebb;} /* possible with above behavior in WINIE */ div#nav li.submenu{background:url(submenu.gif) 95% 50% no-repeat;} div#nav li.submenu:hover{background-color:#edd;} /* this could be just background */ div#nav li a{display:block;padding:0.25em 0 0.25em 0.5em;text-decoration:none;width:6.5em;} div#nav>ul a{width:auto;} /* reset width to auto for modern browsers */ div#nav ul ul{position:absolute;top:0;left:7em;display:none;} /*flip left to popup to left here */ div#nav ul.level1 li.submenu:hover ul.level2, div#nav ul.level2 li.submenu:hover ul.level3{display:block;} ... <div id="nav"> <ul class="level1"> <li><a href="/">Home</a></li> <li><a href="/sitemap/">Sitemap</a></li> <li class="submenu"><a href="/speed/">Speed Up Your Site</a> <ul class="level2"> <li><a href="/speed/1/">Chapter 1</a></li> <li><a href="/speed/2/">Chapter 2</a></li> <li><a href="/speed/3/">Chapter 3</a></li> </ul> </li> </ul> </div>
Meyer has a demonstration without the IE behavior, and Nederlof has a demonstration with the behavior at a Dutch developer site (in Dutch). Note that in this version the submenus do not work in IE 5.x Mac, but the top-level menus still appear. It would be interesting to see these two approaches combined with conditional JavaScript to make them work with IE 5.x Mac.
Conclusion
Replacing graphic or JavaScript-based rollover menus with CSS2-based menus can save bandwidth and development costs. CSS2-based rollover menus transform lists into colorful interactive menus that gracefully degrade, are lightweight, and are search engine friendly.
Further Reading
- Advanced CSS Optimization
- Andy King shows how to optimize your CSS with shorthand properties, grouping, and substitute CSS2-based menus for faster webpage downloads.
- Book Review: More Eric Meyer on CSS
- Eric Meyer’s latest book is a collection of ten conversion projects that teach you CSS by example. Converting to CSS can significantly speed up your site.
- CSS Drop-Down Menu Demo
- Eric Meyer’s original demo of the CSS-only drop-down menus. Does not include the .htc file that makes IE/Win work. The popout menus do not work in Mac IE 5.x. The project files may be downloaded from Chapter 6 of his book More Eric Meyer on CSS.
- Suckerfish Dropdowns
- Patrick Griffiths and Dan Webb show how to create list-based dropdown menus with CSS2 and a dash of JavaScript to fix IE 5+’s lack of :hover support.
- Taming Lists
- ALA shows how to tame the wild unordered list with CSS.
- whatever:hover
- Peter Nederlof provides a JScript-based IE behavior to attach the :hover event to any element.