Hybrid CSS Dropdowns

I know what you’re thinking…“Do we really need another article about CSS dropdowns?” Allow me to convince you. What if we could have one clean, well-structured menu which would combine the dynamism and code-ease of dropdown menus and do away with their main problems (not to mention degrade beautifully)? The problems with dropdown menus are:

Article Continues Below
  1. their secondary options are inaccesible unless you activate the entire menu system; and
  2. they offer insufficient orientation cues for the user. It can be difficult to navigate within a particular section of the site because you have to go back to the dropdown to change pages.

This technique is a bulletproof way to ensure browser compatibility and to maintain usability even for people who have old browsers or difficulty accessing dropdown menus, either because of a disability or a low level of comfort with the dropdown paradigm. It also does a much better job than standard dropdown menus of orienting the user within the site.

Warning: This technique will not work as well for lists that require large numbers of items, where dropdowns either shine or collapse under the weight of their own sheer mass, depending on your perspective.

We’re going to create a hybrid menu that runs horizontally across the window. It has two levels of navigation (in our example, main topics and their associated pages). Our menu will allow for dropdown access to all pages in both navigation levels, display the current choices in the selected topic area constantly, keep the user aware of where he is in the site, and be clean and light to boot.

Sound good? Let’s get going.

First, we need a list#section2

Let’s start with a list of architectural periods and some of their major representatives. We will attach an ID to the

    element and classes of “off” and “on” to the main list items (which is probably not the best solution, but will work for this article’s purposes):

    Get some style on#section3

    This is a great place to start. Simple, semantic markup that can be maintained easily and in one place. It looks like you would expect it to look.

    The first thing we are going to do with our CSS is to display the primary level horizontally (using float) and hide all of the subnavigation lists. We will also set the display for the links in the list to be bold, colored, and have a border.

    #nav li {
      /*float the main list items*/
      margin: 0;
      float: left;
      display: block;
      padding-right: 15px;
    }#nav li.off ul, #nav li.on ul {
      /*hide the subnavs*/
      display: none;
    }#nav li a {
      /*for all links in the list*/
      color: #f90;
      font-weight: bold;
      display: block;
      height: 15px;
      width: 100px;
      border: 1px solid #29497b;
      padding: 5px;

    Next, let’s position our second nav level below the main list, so that when it does show up again, it’s in the right place.

    #nav li.off ul, #nav li.on ul {
      /*put the subnavs below and hide them all*/
      display: none;
      position: absolute;
      top: 33px;
      height: 15px;
      left: 0;
      padding-top: 10px;

    Finally, we’ll show the subnavigation bar for the active topic area, “Modern.” The best way to do this if you want only one central, complete menu file, is with a body class of, say, “Modern,” and corresponding selectors. For this article, which will be published in someone else’s body element and should remain self-sufficient, we have set a class of “on” to the active topic and “off” to the inactive topics.

    #nav li.on a {
      /*change border color for active topic area*/
      border: 1px solid #f90;
    }#nav li.on ul a, #nav li.off ul a {
      /*  cancel inherit of border
          on subnav of active topic */
      border: 0;
    }#nav li.on ul {
      /*display active subnav list*/
      display: block;

    After adding a couple borders, you can see what we have so far here.

    So they all rolled over and one fell out…#section4

    Now, we activate the rollover. This is not much different than any other CSS dropdown menu—the hover is on the li element, so IE will choke due to its poor implementation of the :hover psuedo-class. We’ll get to that in a minute. The following CSS removes the border on the second nav level, sets the active subnav to always display, and sets the inactive subnavs to display when their parents are hovered. We’ll set a z-index to be sure that the hovers always take precedence over the current topic area’s subnav.

    #nav li.on ul a, #nav li.off ul a {
      float: left;
      /*ie doesn't inherit the float*/
      border: 0;
      color: #f90;
      width: auto;
      margin-right: 15px;
    }#nav li.on ul {
      /*display the current topic*/
      display: block;
    }#nav li.off:hover ul {
      /*  display the other topics when
          their parent is hovered */
      display: block;
      z-index: 6000;

    We’ll make it a little more user-friendly, with a background on the hovered tabs.

    #nav li.off a:hover, #nav li.off:hover a {
      background: #29497b;
      color: #f90;

    Check in on our progress here.

    Accommodating our “special” browser friends#section5

    You have two options for users of browsers such as, say, Internet Explorer, which lack support for :hover on anything but the <a> element. You can either leave the menu as is, knowing that it will work beautifully in a few years when all browsers support :hover (knock on wood), and resting in the knowledge that all the navigation options will be visible and accessible to all users, or you can work up a bit of JavaScript to rewrite the CSS selectors in language IE understands to make the dropdown dynamism accessible to all.

    (Working in IE as-is being relative.) We do have to adjust the positioning a little using the asterisk hack:

    #nav li.off ul, #nav li.on ul {
      /*put the subnav below*/
      top: 33px;
      *top: 44px; /*reposition for IE*/

    So it’s working beautifully in modern, standards-compliant browsers, and working in a functional, degraded way, with correct positioning, in versions 5 and 6 of Internet Explorer. With a little help, we can make the hovers work in IE. This simple JavaScript rewrites the hovers as mouseover events, and works for all versions of IE/Win 5x and 6x. Much thanks to Patrick Griffiths and Dan Webb, whose “Suckerfish Dropdowns” got me started with CSS-based menu systems. Their snippet of JavaScript looks like this:

    startList = function() {
    if (document.all && document.getElementById) {
    navRoot = document.getElementById("nav");
    for (i=0; i<navRoot.childNodes.length; i++) {
      node = navRoot.childNodes;
      if (node.nodeName=="LI") {
      node.onmouseover=function() {
      this.className+=" over";
      node.onmouseout=function() {
          (" over", "");

    With a simple change to the CSS:

    #nav li.off:hover ul, #nav li.over ul { 
      display: block;
      z-index: 6000;
    }#nav li.off a:hover,
    #nav li:hover a,
    #nav li.over a {
      background: #29497b;
      color: #f90;

    to add the class “.over” to the list items that require hovering, the list functions just as well for you IE/Win users. Not that you shouldn’t think about a new browser, but for now we’ll continue to support the masses in the manner to which they’ve become accustomed.

    So that’s it. An incremental change, perhaps, over the previous work with CSS dropdowns, but another angle for you to explore for those instances where it really is useful to have the navigation options displayed rather than hidden inside a dropdown menu.

    But can it be beautiful?#section6

    Ok, that’s not it. I couldn’t leave you without a slightly more graphically-rich version to take this technique out of the pedantic and into the real world. With a few changes, a CSS sprite navigation image (thanks, Dave Shea), a photo I took in NYC, and a bit more CSS, we get a menu system which really shows the power of CSS combined with graphic design. Check out the final Hybrid CSS Dropdown, fully functional in all modern browsers.

About the Author

Eric Shepherd

Eric Shepherd is the founder of arkitrave web media, a small web and graphic firm in Buffalo, New York. He is finishing a Master of Architecture degree at the University at Buffalo. He is also a freelance pianist. His work has been featured in the venerable CSS Zen Garden, and he is a strategic partner of Nepo Strategies, a Buffalo-based e-commerce and web strategy firm. He's already working on explaining the potential of clean XHTML, CSS, and Javascript combined with the DOM to his brilliant one-month-old daughter Naia.

110 Reader Comments

  1. Nice example! I tried to get something like this going a while back but failed miserably.

    That extra padding on the top of the nav bar in the parent li sure is nice for getting over to the links and not losing the :hover…

  2. Does this method (or any other that anyone has found) get around a common problem with cascading menu scripts vs. Flash objects?

    You’ve probably seen what I’m talking about: user hovers on primary menu link, which activates drop-down menu, which appears *underneath* any Flash object that occupies the same page space.

    I’ve yet to see a way to fix this. Help!

  3. I don’t think there is a way to avoid that. As far as I know, Flash is just slapped down on top of anything and everything in it’s way.

  4. Great, but everyone of these drop down menus I view say they work in all the browsers, but they never seem to work in Netscape 6.2.

    I don’t know the percentage of people still using this browser, but I can’t wait to see one that works correctly in all the browsers version 5 upwards.

    Still a very good job though!!

  5. Getting drop downs to sit on top of Flash is actually quite simple – simply set the wmode of the flash to transparent.

    See it working here:


    (suckerfish variation).

    I’m not quite sure what this article offers that suckerfish drop downs don’t. Also, its not as accessible as it could be – you should be able to tab through the menus using your keyboard. Instead it relies on mouseovers only.

  6. Very nice, if only i found this earlier…I spent hours trying to achieve this.

    Some bad news: After checking out your final pretty version (link at bottom of tute) in IE 6 I regret to say the tabs are “flash”. They just seem to appear and disappear as they like when hovering over them…

    And I used to think NN 4.7 was a killer, Internet Exploder really does take the cake when it comes to its css implementation.

  7. Oh dang!

    Seems like the issue is the ol’ “Check for newer versions of stored pages” option set to “Every visit to the page” casuing it.

    Hmm, how annoying

  8. There’s also a custom http header your server can provide to IE the stops that behavior. Unfortunately, you will need to configure it or ask your ISP to.

  9. Nice idea, but have you tried to resize this? It looks awful after a few larger text sizes.

    Why can’t you specify most of your CSS paddings and so forth using ems, rather than pixels?

  10. ironic everyone’s speaking of flash yada. This is the best solution for a css version of the Macromedia dropdowns. Very elegent, and much room for style.

    I definitely see this making it onto some of my future websites.

  11. I was just thinking, isn’t there a way to compensate for the text resizing… maybe doing something like combining the sliding doors method with this one? might need an extra <span> or something, but I think it’s doable.

  12. I must say that I still prefer the sucker fish drop downs, having both lists and sublists horizontal means that the entire thing is stuck on two lines whereas with suckerfish it is spread out ofther the page.

    A nicer hybrid would be to see the submenu items (for the active section) as a side bar whilst having an old fasioned suckerfish at the top.

    I suppose that would be achiveable by mucking about with the example in this article but it would take a lot of work.

  13. The end result looks a lot like the navigation I created for a company back in July, only difference is the sub-nav reverts back to the originally selected sub-nav. Don’t know which one I like better from an usability point of view though.

    Here is my implementation, degrades nicely in older browsers or browsers with finicky Javascript support:

  14. …the menu does seem offset to the right from the building image by about 50 pixels in IE 6. Not that I have any idea how to fix that, but just for the record.

  15. Hey Dustin, take a look at my version I posted above. It uses a sliding doors technique and resizes OK, but I use relative positioning to place the navigation, so as you increase the text size the navigation drops down the page and exposes an unstyled area. I should probably fix that 😉

  16. Nice tutorial, but this doesn’t work at all in IE5/Mac. All you get is the background photo…no navigation at all. (Not that I use IE5/Mac, but I do test for it always, as many people still use it.)

    I know it *can* be done (CSS menus) to work in IE5/Mac. Just have a look at Project 7’s Pop Menu Magic and see for yourself:


    Perhaps their technique can be deconstructed sometime. It seems to work in all modern browsers, IE 5 and newer (including Mac), and even degrades nicely in really old browsers (4.x and older.)

  17. Every site I go to now, not many of them have dropdown menus, or anything that’s dynamic (made with css or javascript or flash). The only one that’s pretty good is the one on macromedia.com, which is in Flash. Sometimes css/javascript dropdown menus can be a hassel, especially when the submenus aren’t positioned automatically.

  18. To start: I recognize the irony that this is not implemented on my site; I never could figure out if it is a Safari bug or my own error, and I haven’t had the time to re-address the problem. It is a completely different subnav, however, and was done 8 months before this article was conceived.


    As far as browser support; there could be a number of ways to get this to work in the obscure older browsers like N6 and IE5/Mac. I stopped at the common browsers, and as someone caught, I have a padding bug in IE that I never fixed. I think it’s as simple as a *selector to specify the padding for IE, but I haven’t tried it yet. I simply don’t support N6 and IE5/Mac anymore. If someone’s still using N6, they really owe it to themselves to upgrade, and most Mac users on new-ish machines are browsing with Safari rather than IE. Even Microsoft doesn’t fully support IE5/Mac anymore. And Opera 8? That’s gotta be a bug, I don’t know why it would be collapsing all the tabs. I’ll test again when it gets beyond beta…


    As far as resizing; the point is taken, and sliding doors could be a good technique to use here. I was going for a simple example, and my live implementation (which prompted this article) of this technique does not allow resizing. Since I was using Gill Sans on nepostrategies.com, it had to be an image and I couldn’t use sliding door navigation. However, at least in Safari, going up and down two text sizes still has the subnav text within the blue horizontal bar and doesn’t break anything too much aesthetically.


    And Paul, a top menu with sidebar would be a great next step, and solve a VERY common nav issue. Of course, it wouldn’t be as much hover magic as a positioning system. It would have to be an absolutely positioned child ul, and I’ve thought about it in the past. I’ll have to try something on my next project.

    I appreciate all the feedback!

  19. Just as an aside: the reason I still test for IE5/Mac is because I work for a school district. Darn near every Mac in every lab in every school here uses IE5. Sure, there are some newer machines floating around, but most are *really* old (budget issues.) I think you’ll find that in most K-12 schools (not counting private schools, or public schools in super rich neighborhoods), you’ll get a pretty high percentage of IE5 (or older.)

    I sometimes teach summer (or after school) workshops in web design, and I like to point the students at well designed sites. It’s a shame when a site I find doesn’t work (at all) when the students try to visit. (Although, I must say, it does provide a perfect segue into designing with web standards, and making sure your site degrades gracefully for crappy browsers.)

    So, if students surfing the web or teachers looking for something educational are nowhere near your target market, that’s fine. Otherwise, it’s probably best to make sure any design implementation at least degrades gracefully. It doesn’t have to work (like it does in modern browsers), but it should still be useable (even if, in this case, it only provided the parent links or even just an unstyled list.)

  20. If you put the flash object and embed tags all within a container div, you can adjust the z-index of the div, thereby affecting the Flash movie’s stack order.

    Haven’t really tested this much beyond IE6 and FireFox, though I can say it works quite nicely in both.

  21. It’s a real nice article, congrats. It works the example works perfectly in firefox, but i tried it in Internet Explorer (6.0.2800) and, deception, some major glitches appeared.. the mouseover event (on any links in the menu) makes the selected tab “flashes” .. i noticed that the also nice “suckerfish” menu triggers this bug .. wich, strangely no one noticed.. So i decided to try it on my laptop, wich is running the same xp version BUT with Internet Explorer (6.0.2800) .. no glitch. That’s exacly the kind of things that makes us love ie. F****** IE.. I’ve said it.

  22. Argh. I only have one each of 5.0, 5.5, and 6 to test on. So, for the listening audience, is there definately a problem in a version of IE that isn’t just the page-refresh-every-time thing?

    I don’t have a problem in my version of IE, which happens to be 6.0.2800, but it is on a Win2K system, not XP.

  23. Maybe I am very confused, but I think I have a problem with this (more likely, i am making a really dumb/obvious mistake). I have a #container div that contains the entire site and so that it can be centered. that container is set to position:absolute;. When you put an absolute object (like this menu) into another absolute object (the container), doesn’t the container close to accomodate the menu?

    on another note, i don’t understand why anyone lucky enough to have a mac would use ie! there are so many other good browsers for macs, even the teachers at schools (prob. old and grew up using typewriters and punch cards) should learn to not use ie…

  24. I think it’s a perfect time to just be honest with your students. IE5 is just an old browser and it makes perfect sense why certain techniques won’t work on it. I’m sure the kids in class will understand.

    I dropped IE5 (win and mac) from my testing support near the beginning of this year. My stats show some rediculously low percentage ( .00niner2six??% ).

    It just seems that if you’re worried about making a site truly cross-browseral (and cross-ages), you wouldn’t be implementing techniques like on your site.

    It would be quite a damper if all we ever heard was comment like “It doesn’t work in browser x and browser y.” Look at the entire picture here. It’s simply amazing that something like this even works! Just take a brief peak at the css and you’ll see that it’s no slim file (considering it’s only powering just a site navigation menu). It uses a combination of classes, id’s, tags, even an extra tag because it’s doing so many wild things. … If it weren’t for the brief snippet of js, this wouldn’t even work in IE6.

    I like your sliding doors drop list on that loan site. The only problem is semantically it doesn’t show the hiarchy structure properly. But I’m sure with ’nuff evaluation that could be tweaked.

  25. I just checked the final example with my Opera 7.60, Build 7321 and the navigational tabs are aligned over each other.

  26. Dustin: That’s exactly what I started thinking after I posted that link. Notice I posted:
    “The *final* product looks like…”
    Notice there is no mention of the internals.

    Yeah I should fix the semantics of it, I went and changed the resiability so it uses em’s instead of pixels to position the navigation though.

    That’s what this article has really got me thinking about, the semantics of sub-navigation lists and minimal JS (for IE). It’s hard to shake the old “markup for layout” ideas 😉

  27. how does the hover works on the… well…

    english is not my native language, but i’ll try to say it correctly.

    On the last example (not the one with the images, but the green one that works), by default “modern” is selected. When your cursor goes over the sub-menu of “modern”, the “modern” item’s background goes green. How ? How do you say : the parent element of the a goes green ?

    Thanks !

  28. Can anyone point me to a decent CSS dropdown menu that works with a keyboard? Accessibility – for vision-impaired users, or mobility-impaired users who can’t use a mouse – is an absolute must for me. So far, the menus in this article, and the examples pointed to in the comments, all fail the keyboard test.

  29. Cosmo0:

    The background you’re talking about is in the last instruction of the CSS for that page:

    #nav li.off a:hover, #nav li:hover a {
    background: #d6e3b0;

    It does the same thing for all the five main nav links, not just the active one, in this case. They all get the same background when hovered, just as in the final example, when they all get the blue background when hovered.

    To do a custom background for this item, you would do the same thing, but with more specificity, i.e. #nav li.classname:hover a, or you could write this class dynamically with JavaScript.

    Accessibility. Yes. I’m thinking about ways to make this sort of nav more easy to get around wrt accessibility issues, however, this technique, unless I’m mistaken, should still show the current subnav without any hovering, allow you to select a new top-level nav, and then show the new active subnav when the next page loads.

    Someone who knows more about this that I do, please inform as to whether this is correct.

  30. Hi again,

    You mention: Finally, we’ll show the subnavigation bar for the active topic area, “Modern.” The best way to do this if you want only one central, complete menu file, is with a body class of, say, “Modern,” and corresponding selectors”

    Can someone please give me an example of using the body tag to set the active item for this menu?

    Thanks in advance

  31. Since when is ALA publishing articles with non-valid examples? DOCTYPE anyone [1]? Apart from last example, rest of them look like ’94.

    Second, final example – the one that actually demonstrates the article’s essence in all browsers – fails in IE as submenu is offset to the right. Is this just me, as I don’t see it mentioned in the article. I tried refreshing and all kind of things, but it simply does not work.

    Third, that final examples is image based. I, for one, expected to see all-text example, where the real challenge lies. Images are easy, since one does not have to worry about resizing problem nor about correct positioning of the submenu so that hovering down is possible.

    Forth, this very topic was tackled over 1.5 years ago, when Alex Robinson did first tests about it and asked [2] (few times) on css-discuss list for help on sorting out few issues. I took the plunge and we came up with solid solution [3], that works nice with ems (resizing problem that is mentioned in comments). I tested it with real-life example, and it worked, more or less. [4] If I remember correctly, I think that I sent a message to css-discuss about it.
    Few months ago I perfected that example thus it works just fine now, in all I could test with (IE, Opera, FF, Safari). [5]

    Thus we have over-a-year old technique featured in ALA, which used to publish really ground-breaking stuff. Sad. And who knows what other goodies are buried in css-discuss archives…

    [1] http://www.alistapart.com/articles/doctype/

    [2] http://archivist.incutio.com/viewlist/css-discuss/34658?highlight=nestedsubmenu

    [3] http://www.aplus.co.yu/4ow/alex/

    [4] http://www.aplus.co.yu/css/nestedtabs/

    [5] http://www.aplus.co.yu/css/nestedtabs2/

  32. Thanks for the input.


    About doctype: yes, I didn’t include one for the progress example pages. An oversight on my part.


    About the IE positioning problem: you’re right. I overlooked this when testing; I remember thinking “I need to fix this” and I forgot. That said, I don’t think it’s a huge issue to fix. I mentioned this already, but I apologize for this oversight; it should have been fixed before this was published.


    As far as this being tackled on CSS-discuss, and your example: your example looks very nice, and the code is attractive. I first used this technique on a site last summer, and this article was written in late August or early September; there was a delay in publishing it, and I admit it is perhaps less cutting-edge than it was nine months ago. That said, I think it’s productive for the technique to be disseminated to a wider audience than css-discuss, as probably few designers read it cover-to-cover on a daily basis.


    You’re right: text-based nav is “where the real challeng lies.” However, if my choices are resizing and losing menu options or keeping all my options and not being able to resize, I’ll take pixel-precise absolute sizes anytime. Your example doesn’t even allow me to go up one text size (in Safari; I didn’t look at it in anything else) without losing “about nokia”, and one menu option is lost with each size up. How are you going to explain to Nokia that less-sighted users who want large text simply won’t be able to access some of the nav options?

    The only text size on your example that lets me read all the options is about the same size as the text size on my fixed, image-based nav. And, if a user resizes, they will still get all the nav options.

    That said, if you take your example and add the ability to resize without losing important nav options, it is quite elegant, and could actually be used on a production site. There’s no reason sliding doors couldn’t be used here, I just chose to keep that aspect of the example more simple than that.

  33. Nice.

    Although the coding came out better on yours, Veerle’s version has a better look. Maybe yours would be better if I saw it used in an actual website design. Anyway, if anyone hasn’t seen it yet (not sure if somebody already posted this), Veerle made on around the same time. http://veerle.duoh.com

    She had some problems with hers, wanting it to only use 1 image, so she was hoping htis article woul help with that

  34. The CSS menus I’ve seen, when used with a keyboard, display the top-level nav and one of the sublevels. That creates one issue – you’re presenting less information to a keyboard user than a mouse user. Yes, it’s somewhat functional, but it’s far from desirable.

    The slightly more significant issue is that in most cases (not all), as you tab through links, you will tab through ALL links, in order – even the ones buried in submenus that you can’t see. So you may tab to a link, get a visual indication of where you are, then hit tab, and you’re lost. You see no sign of what you just tabbed to. Hit tab again, same thing. 5 or 6 tabs later (assuming you haven’t given up and left the page already), and you pop back onto the screen at the next top-level menu item. And then you’re gone again.

    Accessibility is not just about “does it work?”, it’s also about “does it work well?” Unfortunately, I haven’t seen CSS menus that work well, yet.

  35. OK…so, as long as the selected subnav is being displayed, the user doesn’t get the hover benefit to access all the options, but isn’t prevented from getting to any of them. I will start thinking about scripting solutions to get around this. Maybe an activation of a subnav with a focus event?

    Are tabs supposed to cycle through items set to display:none per spec? This seems to me to be a browser issue. Does anyone know what the behavior “should” be for subnav items?

  36. Just to clear one thing out – the prior art wording you used urged me to re-read my post and realize it can be understood wrongly.

    I’m not accusing you of taking-over the code Alex and I did and then publishing as yours. I believe that you have never seen it, which is the biggest shame at all, as you could save time on initial development and solve the remaning problems. I simply mentioned that this is not new and “new” is something I expect from ALA article.

    Or at least expect to solve the resizing/overlapping problem you mention yourself. That would be cream of the cream.

  37. I didn’t actually take your post that way; I apologize if I was a bit defensive 🙂 Your subject line initially was a little provocative.

    My response was only meant to point out that your example has some serious problems – nav options should not ever just vanish with a little text-resizing, and this example does not have this issue because of the image-based main nav. Neither is perfect.


    As far as ALA and “new”, that’s up to the editors. Part of this issue, as I said, is a publishing schedule – ideas don’t go from experimentation/blog entry to article to published overnight. Another angle, I assume, is the desire of ALA to communicate ideas to those beyond the world of lists like css-discuss.

    I “invented” faux columns (along with probably many other people) well over a year before Dan’s article, but I didn’t write an article, and the web community as a whole hadn’t implemented the idea yet, so an article was a productive addition to ALA.


    Finally, TextDrive is having problems, and my site is down today; if anyone has tried to send email, sorry about the bounce and please try again later.

  38. Once I started thinking about this problem again, once natural solution for main item wrap comes to mind: define menu width in ems too.
    If the text size is enlarged, the menu itself will enlarge and all happy (I updated the example on my site to show this).

    Every solution has weak spots. For this one: small screen size and large fonts will yield horizontal scrollbar. Which is not a problem but an annoyance. On the second glance – I have yet to see a person using 800×600 and Largest text-size setting.

    I usually enlarge text size when I’m using large resolutions on small screens, like 1400×1024 on my Dell 15″ laptop. In this scenario, this works like a charm.

    If you have a pixel-set graphic design, then this will lead to menu going outside the right edge. Another thing can be tried then – setting min-height to a value that would accomodate at least two rows of text. It depends on layout in question really. and good layout that should take into account issues like this.

  39. Dustin:

    I think you missed a very important part of my post: this is a closed environment (school computer labs) with old computers. There are no browsers to upgrade to! IE5 is the most recent browser that will run on those machines. The sad thing is, you’ll find this in *many* K-12 schools throughout the country. It’s one area where it’s not always possible to simply “upgrade the browsers.”

    Also, if you look back at my initial post, you’l see I linked to a list based CSS solution that DOES work in all browsers, even IE5/Mac, so my point is: if it’s worth doing, why not do it right? (No offense to the author…it’s a fine article, and a good learning tool.)

    It *is* possible to get this functionality that is truly cross browser, and that degrades very well for really old (4.x and older) browsers, works on cell phones and PDA’s, etc. So, I think it’s a bit too convenient to simply say “just upgrade your browser.” Some people can’t. It’s that simple. I think it’s safe to say the overwhelming majority of those who visit this site are designers/developers of some sort. We tend to be on the cutting edge, and will always have the latest technologies. If you look at the browser stats for this site, you probably won’t see many oder browsers. But, what if youre site has educational value? You should make sure, then, that it can be used by the target audience, which in this case would tend to have older browsers (if we’re talking K-12). If not, sure you can just ignore v5.x browsers. But, if it’s very much possible for this (and most) designs/tools to work in v5.x, why not just do it?

  40. I have heard, the difficulty with something like this is how precise your movements have to be to navigate the second line. We utilize a very similar navigation system for our University websites, albeit yet another implementation. http://www.unl.edu/webdevnet/

    In the example there’s plenty of padding to make it more forgiving, but on sites that have many many links the padding has to be reduced – making it difficult for people to get to the line 2 links. Adding to the problem is that you must remain hovered over the second region to show the links. If the user slips off the second nav line, all is lost.
    The CSS example is great, but with a little javascript settimeouts and careful planning – we could really have a nice compliant version of Macromedia’s (Flash) navigation system.

  41. If anyone tried to contact me directly or visit my site; things are back up now and email shouldn’t bounce back. A scary outage at theplanet; 12 hours or something like that, caused by a blown fuse…

    Thanks for the Opera 8 update; I’m glad it was a transient bug.

    And I like the use of timeouts for the menu system at UNL, Brett. Very nice addition.

  42. Thanks for new and useful tabs – I’ve been looking for similar one for a long time now and I also tried to create something similar, however, without any proper results.


  43. “I’ll take pixel-precise absolute sizes anytime.”

    As the designer that is your choice, some of your users won’t thank you for it, mind.

    Why the obsession with dropdowns? Go on, force your users to follow precise cursor paths to their chosen link or risk triggering a neighbouring set of options and frustrate ’em.

    But I enjoyed the read and discussion – as always!

  44. Is that if the user doesn’t follow the precise path and can’t handle the dropdown, it doesn’t keep him from the information; I think that was said early on in the article.

    The obsession with dropdowns is that they provide quick access to many pages without having to click through a set of interim pages. For users that know where they want to go, this is a useability benefit.

    For those that don’t, this type of menu still allows them to access everything, unlike traditional dropdowns where all the options remain hidden in the menu unless hovered.

    Based on the several really nice implementations of similar menus that have been posted on this discussion board, it seems that others have found this idea, in various forms from Flash to CSS-based, to be beneficial.

    One’s frustration is perhaps anothers’ benefit. I guess that’s the crux of any of these disucssions. Nobody’s saying that any one technique is right for every website. As a user with manual dexterity and a knowledge of what I want, dropdowns are beneficial to me.

  45. Hi
    This article is really nice and everything works perfectly – except in ie6: the submenu (.old ul, .off ul) has an offset of some pixels in the final css example (hybrid-4.html). Can it be a problem with: padding-left: 60px?

    But we all now how to fix this 😉

  46. I don’t see how that is much of an improvement.I was especially put off by the way it uses block and none for display, a technique that is known for a long time now to be an accessibility issue and was published here [1].

    This solution still has the same problem as any CSS nav solution:

    1) It is not keyboard enabled – Visitors might have to tab through a lot of invisible links to get where they want (mentioned in one message before this one already)
    2) It still is a matter of “sitemap as navigation”. Why do I need all links to every page in the site on every page? For the high end user, that is fine, but for people who have problems with too many links (switch/keyboard access, screen reader) it is just annoying. Hiding things doesn’t remove them. [2]

    A _really_ helpful hybrid navigation would only add the second layers when the user has scripting enabled and uses a mouse – or has chosen to get them. This is perfectly possible with CSS and JavaScript, the only problem is the maintenance in the markup and the script, but that is something that can be maintained in the backend, too (a PHP script writing out the HTML and the JS depending on how it is embedded).

    Back in the days when we started playing with DHTML we did it completely wrong by making the whole navigation dependent on JavaScript, maybe it is time to make JavaScript work for us and only add the extra bits for those who can use them and want them.


  47. Can this type of menu be navigated by keyboard users (i.e. people who cannot use a mouse… for example, people who use screenreaders)?

  48. > Visitors might have to tab through a lot of invisible links

    Isn’t that the whole point of the “Skip to content” link that is quite common?

    Although I agree that CSS display properties can open up accessibility issues, isn’t the real source of the problem screen readers attempting to render a screen stylesheet is if it was aural? If that’s the case, it would seem like the easiest solution is to create a stylesheet just for screen readers and provide a link to that stylesheet right at the top of the page. That way the special screen reader CSS could be activated by the visitor (and carried throughout their visit, by cookies).

    I really like sub-nav, at least on bigger, commerce based sites that get quite deep with navigation. I don’t think arguing against the usage of nested navigation really holds water if one is arguing accessibility. These issues can be worked around without dropping the nested navigation altogether.

  49. Justin: How could you work around these issues with skip links?
    First of all the navigation is one entity, so you’d need to put a skip link before every nested list to skip it.
    Secondly screen readers also offer a list of links in the document to navigate directly, and the links will show up there.
    Even when you can navigate them, it is just really annoying to get all that information that just is not needed to navigate the site.
    I agree that nested navigations can be a handy shortcut, but they should only appear when you can use them.
    The flaw of screen readers trying to render visual stylesheets is bad, but I guess it was needed to make them usable UAs for browsing, much like browsers do render invalid HTML, whereas they should not.
    It does not matter how the CSS is when the HTML/content is just too much. You don’t print the index of a book on every page, you print it at the end or at the beginning.

  50. By this analogy, each page in a website would have a link to only two other pages and a site map.

    I understand what you’re saying, but the whole point of the web is that we can jump to many places from one place. I agree, the scale can become unworkable, and will be a problem with large lists until screenreaders and the like get smarter, but I’m not satisfied with a comparison of the web and a book.

  51. And it is matter of judgement how many links are bearable and how many are just too much. What is the important bit of the web page? Its content or how many more are available in the whole site? Do we want to help the visitors to find what they came for or do we want to offer them everything at once?
    I never claimed web sites should be like books and we should only have links to the next, last page and the sitemap I just compared offering all links on a page to printing the index of a catalogue on each page. We offer too many options where they are possibly wanted but not needed.
    Nested navigations are an extra offer to avoid a page load and a drilldown in the navigation.
    It is for us to ponder if they are worth it when they can be a bother to use for some.
    The visitors benefiting from the shortcut are the high end users with our CSS available and able to see the showing and hiding and navigating via a mouse – if we use CSS only (with JavaScript you can create navigations that can be enabled by keyboard, too).
    The other visitors will see the whole navigation at once, which can be far too much information.
    The logical step would be to only offer the extra information to those who want it and not assume that everybody does benefit from it.

  52. Who are these “high end users, with CSS enabled” you speak of Chris?

    I don’t see how you can shrug off the typical visitor, with CSS on (of course) and Javascript enabled (I think less than 2% have Javascript turned off) as a high end user who isn’t worthy of sub-menu navigation.

    What you’re suggesting (adding sub-nav dynamically) seems to be putting far too much reliance on client-side scripting when your end result is something that 90% of the visiting population (or so) *can* take advantage of.

    Couldn’t I just as easily put a link right in the top of my document which when clicked will load my site, but without the sub-nav? Or (as I tried to explain earlier), just add another stylesheet that hides the sub-nav from all?

    I don’t know, seems like a draw I guess. We could probably argue the advantages/disadvantages of each method to no end.

  53. I had this kind of menu going for a long time at my company. I eventually changed it to be a traditional drop-down. While the hybrid here does give great clues to navigation, there are also a few major drawbacks that take away more than they add in my opinion.

    The worst problem is the mouse space. When you want to change a section, you mouse over it, move down, then move across to the item you want on a thin line, being careful not to go outside the line. If you lose the line, you have to go back and start all over. Traditional drop-downs don’t make you change direction while navigating, you just drop right down to your item. Plus there is lots more room horizontally with normal drop-downs than vertically with hybrids because you’re not trying to stay within just one line. This makes navigation MUCH easier and not so much an exercise in mouse accuracy.

    Next is that since it is horizontal, there is a limited quantity of submenu items that can be put on it without rolling over to the next line. Usually these kind of things are kept on one so you don’t get blank space from one carry-over and because it’s more difficult to tell that these are sub-items when they’re in a big jumble. So the one line limits you.

    Also with the one line, if your right-most tab only has one or two sub-items, you run into problems. You can’t position the list all the way to the left because it will look like the sub-items are part of some other tab or no tab at all. (unless you use a high-contrast tab structure like the example) You also can’t position the left-most sub-item with the left of the selected main item because it will quickly run off the right side of the page. And it becomes a bit tricky to align the main and sub-items to the right, plus it messes up the first item.

    Last is the obvious two-level limit in navigation. This limits both ways. If you want to have a menu item with no sub-items then you’ll have to have a blank line or it will jump down when you roll over another item. This looks weird to have a blank line because you wonder why it’s there. On the other hand, you can’t go more than two deep. Otherwise you’d have to either do traditional drop-downs afterward (weird) or continue the lines down and down (even weirder) or lay the lines across the whole page over top of the current page as you dig deeper and deeper. (which hides the page)

    As you can see, all these things eventually added up to the return of traditional drop-downs.

  54. The “typical visitor” who I called the “high end visitor” has JavaScript enabled and our CSS for display. These are the only ones that can use a dynamic navigation (JS is needed to ensure keyboard access as most browsers don’t support :focus), right?
    That is why my stance is to make it available to them but not force it on the others.

    Let’s check the facts.
    – All levels of navigation on each page are not a need, they are a shortcut – a “nice to have”.
    – Users without either JS or CSS or both will get a lot of links they don’t need.
    – We cannot rely on Javascript being available (it is not in high security areas like financial institutions for example), but we can test if it is available.
    – We cannot rely on CSS to get rid of the unnecessary links as visual hiding is not removing them from the document.

    Therefore the most usable and unobtrusive way is to:

    – Give the visitor the bare minimum of navigation and an option to have an “extended navigation” – an option that can be stored in a profile or a cookie for the next visit.

    Or if that is an unwanted step:

    – Give the visitor the bare minimum and expand it only when JavaScript is available.

    The latter option would mean no difference in the site experience, but is more flexible.

    It is the same logic we applied when we moved screen furniture from image elements to the CSS.

  55. i use a div like someone else wrote that will position my whole site. Now the navigation will work in Firefox but in IE6 it will not allow me time to select a subnav. The thing has to do with position:absolute but is there a way to fix this problem? i really need this… cause 12 hours of transparancy in IE hack and now this i cant handle this anymore:S

    well ill hear… maybe

  56. Before everyone praises this approach it should be clear that such menus imply more or less severe usability problems especially for elderly users or users with motor problems.

    Personally and apart from this, I liked some ideas presented in the article.

  57. Hybrid CSS Dropdowns… loox really bad in Safaribrowser.. Pity… GREAT STUFF though!

  58. >loox really bad in Safaribrowser..

    Loox really good in 3 versions of Safaribrowser ALA tested it in or ALA not have pubbblished it.

  59. Looks good in “standard/default” mode but when
    I ctrl+ in Firefox 1.0.2 to increase the font
    size, only the sec-nav change, the tabs don’t.
    🙁 Same for ctrl- to shrink the font.

    After 4 ctrl+ the sec-nav starts to wrap and
    the bottom half of the words are cropped. 🙁

  60. All I get is the image, without the menu. It works in Navigator for the Mac….

  61. Why doesn’t anyone use the function getElementsByTagName()?

    It’s much more elegant than using a for loop to iterate through each of an element’s children to find all of one type of tag.

  62. Does anyone actually USE that browser any more? As in, anyone who matters?

    I’m a firm believer in discarding broken or out of date browsers from my support roster, since most users of Netscape 4.x and IE Mac will be pretty much used to dealing with pages that break on their browsers anyway.

  63. I was looking for a way to make pulldown menus without browser detection, because clean xhtml/css was supposed to get rid of browser detection scripts. Of course IE not supporting the hover function for anything besides ‘A’ makes this hard, but I keep hoping for a different solution.

  64. I tried to view this on IE 5.1 for Mac and it doesn’t work. Should it work?

  65. I did one, but i guess that this version showed have a little trick

    check this one…

    i built using some advices from a list apart.

  66. I’ve noticed the IE6 offset issue as well. I made a menu and once I check it with IE6, I had the same problem as the example at the end of this tutorial. Is there a fix for this IE6 bug? It’s kind of frustrating spending the time to follow a tutorial and then realizing that it won’t work in IE…

  67. Just an FYI —

    using Safari 1.0.3(v85.8.1) [via 10.2.8, Old School I know…] having a couple issues:

    * am seeing each main menu name, below the related submenu items, indented, half line below (obscurring submenu text).

    * Under the Modern tab (orange), the hover of submenu items displays the main menu background (blue bg with clipped-corner) in the submenu, and changes the text color to orange (instead of blue).

    * Rolling between main tabs is inconsistent. Sometimes it works, sometimes it doesn’t.

    Something strange is afoot at the Circle-K

  68. another FYI —

    On my system, the submenu at arkitrave.com does not work totally either.

    Submenu is always stacked on left edge below Home tab. And not clickable, as it disappears when I come off the tabs.

    Not a CSS-guru by any means — just here to learn. I don’t think my Safari config is altered beyond stock.

    But maybe it is just my system…

  69. I built the site well over a year ago, and the dropdowns have nothing to do with this article. They work like a charm in everything except Safari, and I’ve never figured out whether it’s my bad coding or Safari that causes them to break in Safari. I am aware of the problem. Know that it is a different set of code, as the current article works fine in the Safari that I tested in. I’m not sure what the problem is for the older version in 10.2.8.

    Maybe I will go back to JavaScript rollovers 🙂

    No, seriously, thanks for all the observations from different versions; it is impossible to test for all of these browsers and OSs. I do pretty well with my local PC/Mac Intranet and 9 or so browsers, but it’s all under Win2K or OS10.3.

    I have on my list to fix the indentation problem in IE6 – I don’t yet know what’s causing that and I’ll post something to my site when I figure it out. That said, don’t hold your collective breath, as I’ve got a busy spring coming up.

  70. Hi Eric — Sorry to divert focus to your site… given it’s different code and older. (should have read every response prior to mentioning it)

    Thanks for an outstanding article!! Was not trying to be a pain-in-the-rear… only trying to explain the issue with 10.2.8 specifically.

    popartpopeye mentioned on page 7 (in not a very helpful way) that his Safari wasn’t working properly. If he was having the same issues as I — thought you could use some more info about specifics.

    Keep up the great work though!

  71. I’ve implemented the menu on an elastic site with two main problems. 1) (I think everyone has already discovered) My main-level links wrap, but they are then hidden by the “on” sub-nav that is positioned directly below line 1 of the main-nav. Any way around this? (he asks, expecting silence).

    And 2). Because the site is elastic, the sub-nav width needs to be set to 100%. But in IE, when the width is set to 100%, the sub-nav li’s all appear one vertically on top of the other. The only way to render them horizontally is to specify the width of the ul in either em’s or px’s. Anyone know of a way around this?

    NOTE: The implementation is located at the linked site (which is hosted on my computer and may or may not be online). The site is essentially a personal experiment in xml from start to finish. Pay no mind to the content. 😉

  72. Looking at the final menus in Firefox and IE6 side-by-side reveals that they don’t *quite* display the same. For example, in Firefox, the header image and menus are flush left. However, in Opera and IE6, this is on a Linux system, the menus start with a space between the left side of the browser window and the edge of the menu instead of flush with the leftside browser window as is the case with Firefox. Is there a way to compensate for this behavior without trashing the display in Firefox? The more I learn about web development the more I loathe Microsoft and IE.

  73. Someone know a menu like this?
    Option1 | Option2 | Option3
    option2.4 >option2.3.2

    The current no have option2.3.1

  74. In my opinion, CSS has not yet reached a stage where it can gracefully handle complex behavior like nested drop-down menus.

    This is most evident in the example if you hover over the right-most parent (“Digital”) and then quickly move to the left-most child (“Xenakis”). If you can do this quickly without losing the “Digital” menu items, then you’re more dextrous than the vast majority of mouse-users.

    The CSS :hover pseudo-class simply has no tolerance on most browsers for any accidental mouse jittering. It would be nice if it could be specified with a given timeout, for example “ul:hover(5)”, but alas, that is not available – and perhaps it shouldn’t be. The purpose of this pseudo-class is to simply highlight an item when it is clickable, not to provide complicated behavioral scripting capabilities. CSS is a brilliant language for style, but every “CSS Behavior” hack that I see just seems to be a stretch for no purpose other than showing off what is possible.

    (Granted, that’s a fine purpose and something that should be done in the name of innovation, but it’s not a good methodology for creating accessible and profitable websites!)

    A javascript solution, otoh, can easily be created that will use exactly the same degradible XHTML and similar CSS styling. In this way, you can allow your users to hover or click a parent, and don’t change it until they hover/click another parent. This is the default application behavior that most users are used to, and it is more forgiving of often imperfect mouse movements.

  75. who knows.
    It seems I am having problems not with flash
    but with multiple lines of drop downs.

    ———– ———– ————
    drop down1 drop down2 drop down 3
    ———– ———– ————
    ———– ———– ————
    drop down4 drop down5 drop down 6
    ———– ———– ————

    the list hides behind the

      heading below it. is this just a z-index or how the flop am
      I supposed to get it to work. any ideas??
  76. its based on pixles, but even worse it cannot be zoomed. Thats just crap, nothing else.

    Dropdownmenus in general are a problem, better use asyncronic server connections (ajax) and refresh menus statically, if you mess around with javascript anyway.

  77. Sorry, but this menu isn’t working on IE 5.2 Mac. It is working in Safari.

  78. What if your menu is centered on a page? How the heck are you supposed to position the sub-navs since this example is crippled by using actual pixels?

  79. “This technique is a bulletproof way to ensure browser compatibility and to maintain usability”.
    I believe the above sentance should be removed from the article; because IMHO this solution has serious issues:
    – poor browser support,
    – text is not scalable,
    – list items are not accessible in IE when JS is disabled,
    – and, AFAIK, tabbing navigation is not possible in any browser.

    Months ago, I have published a solution, trying to address each problem:

  80. I tried this and it works very well except the subnavi which disappers immediately when I move the cursor away from a tab. So I can’t access the subnavi at all! Do you have a solution for this? Thanks!

  81. I’m still searching for a CSS solution that is compatible accross all (most) OS platforms and browsers. I liked the look of your menu, but when I tried it on OS-X and IE, I get no menus at all!

    Mac OS 10.3.9 (Apple’s most current), and Internet Explorer for Rel. 5.2.3 (MS’s most current and final version)

    Anyone else have this problem?

  82. Your menu behaves badly in Firefox when I increase text size (Ctrl++). Menu items disappear, extraneous lines appear, etc..

  83. The problem with CSS menus is that navigation is very important and problems with like the flashing effect, cross-browser issues, etc. make it less than ideal.

    Another problem I have with CSS only menus is that it tries to do behaviour in CSS for which CSS was not designed. CSS should IMO be presentation only.

    Also with XHTML markup, CSS styled but Javascript powered navigation you can do some eye candy like the menus I did for my MXR CMS product. see http://mxdemo.infireal.com/ (P.S: the markup is terrible, its on the todo list)
    The menu does a roll-up and fade out effect.

  84. I’m having a problem implementing a list in FireFox. When I added the style info into my stylesheet, all of a sudden FireFox stopped recognizing all of the stylesheet from that point down. I can’t figure out what’s causing this problem. IE can still parse the entire stylesheet, displaying the list properly. (The list is taken from the ALA 2002 article Taming Lists by the way.)

    Any suggestions? Thanks!

  85. I was just checking out the linked examples and they look fine in Safari, but totally not working in Explorer??

  86. Sorry for a little off-topic, but I’m struggling with one thing, which maybe you know how to solve

    I want a very simple horizontal menu, based on list

    I’ve done it, but I wanted it to have a custom bullet, so I used list-style: url(/image.gif); in the ul style declaration

    it appeared ok in mozilla, but there is NO image neither in opera nor IE.

    well, if I change the image to just ‘circle’ or ‘square’ it does not appear in those browsers anyway

    Is it possible to to have bullets (custom too) in horizontal menu based on ul ?
    it’s easy to make it in vertical on, but I have not found any example of such menu turned to horizontal…


  87. I am in the process of setting this up and I can’t get it to center on the page like the rest of my page does. I have a container div around my whole page with margin-left and margin-right set to auto, but the secondary nav is always left aligned. Anyone know a remedy?

  88. I was working several mothes ago on a similar NAV on a client site http://www.cfatb.com/ using extensively the sluckerfish inspiration.

    I enhanced it to fit our requisites and it seems that it works good on many major browsers. Of course the CSS is free to use as well as the HTML code itself. I think I made some mistakes but it works pretty well.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA