Suckerfish Dropdowns

by Dan Webb, Patrick Griffiths

128 Reader Comments

Back to the Article
  1. Over at http://mobius-restaurant.com/bar/menu.htm I’ve set up the menus, and they work brilliantly in IE6 and Opera7.

    However, I’ve run into a problem in Mozilla1.5. The restaurant (in the middle) dropdown works well until you hover over an item that happens to be on top of the <div id=“menu”> – at which point the menu disappears.

    It only happens if <div id=“menu”> uses overflow: auto; or overflow: scroll. Make it hidden or visible and the menu works just fine.

    Any ideas bar moving <div id=“menu”> further down to stop the dropdown going over it?

    Copy & paste the code below to embed this comment.
  2. I have only recently found out about this site.  It is wonderful!

    I have set up a menu on my test server and they work great everywhere except Safari version 1.0.  I read the earlier posts regarding this issue.

    I have tried numerous tweaks to get it to work, all to no avail.  I am wondering if anyone else has been able to successully get a menu to display properly in Safari 1.0?

    Copy & paste the code below to embed this comment.
  3. I’ve got the drop down menu working fine in IE and Opera, but in Mozilla 1.6a and Galeon, the hyperlinks don’t work. When you do an onClick event, the sub menu disappears but nothing else happens. In Konqueror, it’s even wors. The Drop Down List doesn’t even appear. Any help would be really appreciated as I do want this to work.

    Copy & paste the code below to embed this comment.
  4. I too would love to find a way to make this usable for Safari 1.0 users – even if it was just hiding the submenus. Currently it looks like trash. So sad. :(

    All in all, it’s a beautiful menu solution. My favorite so far.

    Copy & paste the code below to embed this comment.
  5. This technique is sooo close.  It’s useable, but really difficult to implement with cross-browser consistency unless you tailor your design to accommodate browser quirks and limitations, as your demo does quite effectively.

    But there’s another concession you neglected to mention.

    I’ve noticed that in the markup of the working demo (“pretty” version), the link in each top-level list item is wrapped in a semantically / structurally meaningless set of div tags:

    <li id=“first”>
    <div>Overview</div>

    The need for this isn’t explained in the article; but as you evidently discovered, without the extra div all current browsers except ie 5.5 & 6 will insert space after the link when you roll over it—shifting the list-item links following it to the right on mouseover.

    The behavior is unacceptable.  But the needless div is also an undesirable compromise.

    If anyone can come up with a better workaraound, please post it here.

    Thanks.

    Copy & paste the code below to embed this comment.
  6. Can anybody tell… why this nice little dropdown do not work in this demo ??
    http://www.positioniseverything.net/guests/3colcomplex.html
    I have tested it in Netscape, Mozilla (Mandrake) and Galeon and it works fine, but not in IE 6.1.
    Can anybody help?

    Copy & paste the code below to embed this comment.
  7. when i add this line

    li:hover, li.over ul

    mozilla stops working and when i hover the menu flashes and then it shifts some of the top level elements to the next line.

    Any ideas?

    Copy & paste the code below to embed this comment.
  8. The only the way I can think of to get round the problems of safari 1.0 is to use browser sniffing and then use absolute positioning. However, this totally defeats the whole purpose of using the menu in the first place…any javascript guru’s out there who can know of some other work around?

    Copy & paste the code below to embed this comment.
  9. Nice menu but its not 508 compliant.

    I’m a real nut when it comes to standards.

    Chuck

    Copy & paste the code below to embed this comment.
  10. This is very short and sweet, and I appreciate that.

    Question… isn’t there some way to keep the menus on top/above of other content, like forms and images, instead of the menus hiding underneath them?

    Copy & paste the code below to embed this comment.
  11. Finding this article made me extremely happy, up until I got far in my project and then realized this horrid situation with IE – the drop down menus started flickering everytime my mouse is over them!
    As I went to the suckerfish example I was shocked to find out that they were flickering too.
    Strange, the only thing I did was installing STYLEVISION 2004…

    Any ideas why this is happening?

    Copy & paste the code below to embed this comment.
  12. I found a post here that helped me figure out what was the problem with the flickering effect on IE – it’s the “Check for newer versions of stored pages” set on “Every visit to the page”.  If you change that to “Automatically” it will work fine.  But this a major setback…  Anybody have ideas to fix this bug?

    Copy & paste the code below to embed this comment.
  13. I am seeing a similar problem as can be seen
    here:

    http://www.pizza.org/asta/

    Any ideas on how to fix this?

    Copy & paste the code below to embed this comment.
  14. Welll, I don’t like it. A background image for a DHTML Menu is a big no-no. I have built my DHTML menus on simple principles, as can be seen at sfhe.cjb.net. As PPK noted, A List Apart is nothing more than some childish wow-factor scripts.

    Dante has spoken.

    Copy & paste the code below to embed this comment.
  15. After running this fine menu for a few days, I begain to receive a JavaScript runtime error:  “Object Required” on the following element:  i<navRoot.childNodes.length

    Here’s the script:

    /* CSS Menu Styles adapted from alistapart http://www.alistapart.com/articles/dropdowns */
    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. {
    this.className+=” over”;
    }
      node. {
    this.className=this.className.replace(” over”, “”);
    }
      }
      }
    }
    }
    window.

    The .NET generated web page using this script is XHTML Transitional compliant.

    Any idea what may be happening?

    Sam

    Copy & paste the code below to embed this comment.
  16. I found the cause of the JS error I mentioned previously within minutes after making the post.

    Funny how that happens so often.

    My .NET page hides the drop-down menus at times, which effectively removes them from the XHTML completely.

    I’m not a JS programmer.  Can the JS be modified not to error if no menu is present?

    Sam

    Copy & paste the code below to embed this comment.
  17. Sometimes old dogs learn new tricks.

    Here’s a revision that doesn’t error out when the menu isn’t present:

    startList = function() {
    if (document.all&&document;.getElementById) {
      navRoot = document.getElementById(“nav”);
      if ( navRoot )  {
      for (i=0; i<navRoot.childNodes.length; i++) {
    node = navRoot.childNodes;
    if (node.nodeName==“LI”) {
    node. { this.className+=” over”; }
          node. {this.className=this.className.replace(” over”, “”);}
      }
      }
      }
      }
    }
    window.onload=startList;

    Copy & paste the code below to embed this comment.
  18. use the z-index.

    If you set the z-index of your main UL to 2 or 3, it and all its contents (incl. any popup menus) will appear on top of anything else on the page.

    Copy & paste the code below to embed this comment.
  19. That article was the most god-awful piece of crap excuse for a DHTML menu I’ve ever seen. And I’ve seen zpub.com. If you could take your nose out of Mozilla’s ass for just a second you’d see a lot. “Gee. Why not make the CSS work in every browser except the most used one”. It’s like I said:
    “A List Apart is nothing but pages with
    blah-blah wannabe web-developer text that have
    pretty pictures at the top.”
    Moded.

    Copy & paste the code below to embed this comment.
  20. One thing I cannot figure out is how to align the drop down list ul to align to the left with its parent li.  It always seems to be indented by 1px.  See the first drop down menu (overview) of the suckerfish drop down (http://www.htmldog.com/articles/suckerfish/example/).  Would there be an easy fix to get this to align left?

    Best Regards,

    Scott Taylor

    Copy & paste the code below to embed this comment.
  21. I have created a simple behavior (.htc script) for IE5+ browsers to emulate :hover sub-classes with help of normal classes.

    And creted an example for drop-down lists.

    You can find it here:
    http://www.hszk.bme.hu/~hj130/css/list_menu/hover/index.html

    Copy & paste the code below to embed this comment.
  22. Alrighty. I stumbled across this page last night, and I am happier. I’ve been looking for an ‘easy’ way to do just what this script does.

    But, in trying to make NS7.1, IE6, Opera7.23 happy, I am struggling. I’m in the process of re-laying out my site and need to at least get the top2.htm file right so I can include it across the board. That might be wise, but it’s a work in progress.

    Can someone tell me why my menu is centered in NS, but not Opera or IE? I think it’s a margin issue…

    this be the BSS beast that keeps growing..

    http://wanderingproductions.com/images/main.css

    and this is the page:

    http://wanderingproductions.com/top2.htm

    as you can see, the pic is centered. the rest ain’t (outside of NS7). I am… perplexed.

    thanks folks
    tb

    Copy & paste the code below to embed this comment.
  23. Sean and Dante,

    I guess giving out advice is easy from your lofty position. I mean, inventing a browser with no refresh, that doesn’t show you what page you are on and that can’t even spell the month correctly – that’s pretty intense stuff.

    http://www.geocities.com/seanmhall2003/homepage.html

    Matt

    Copy & paste the code below to embed this comment.
  24. I was working on a DHTML menu when discover this CSS Dropdown and love it. But there’s some things that I wish to know (all about graphical interface):

    1. How to implement a css rollover for the first list and a different rollover for the second one. (I have one working great in Mozilla Firebird but doesn’t work in IE6 and Opera 7).

    2. Is it possible to use this CSS Dropdown menu to make something like the http://www.mediatemple.net/ navigation?

    Thanks in advance.

    Copy & paste the code below to embed this comment.
  25. Noemi, thanks for your tip on Z index! I thought it could be done, just didn’t remember the name for it. :)

    Now for my next confusion: can these be more than 3 menus/links/divs wide? I noticed the examples using this are just three. Is this because the divs/LIs are float left, none, and right? Could I make more menus by using a table first then put each div/LI in a td and not use the float?

    ..something like that?

    Copy & paste the code below to embed this comment.
  26. I was wondering if anyone tried pre-caching the background image for the drop down menu, as you would for javascript rollovers.

    It would appear that IE is not caching the image, obviously.  It is interesting that changing the setting for “check for new versions of cached pages” to anything but “every visit to page” corrects the situation.

    It never was necessary for Javascript rollovers, where you would change the source of the image, once the image was downloaded, it remained.

    Copy & paste the code below to embed this comment.
  27. Let me add my congratulations on this clean solution that works so well.

    With your UL/LI drop down menu in place, is there a way to structure things so that unordered lists in the text below these menus can be presented in its default (or similar to default) format?

    Copy & paste the code below to embed this comment.
  28. I tried two different approaches to this. Maybe you will have better luck than I did.

    First was to give a class (or id) to all the lists used in the menus, with the thought that lists elsewhere in the site wouldn’t inherit the styles for the menus that way. But I didn’t find a way to do that and keep the menus functioning.

    Second was make a standard list class with basics defined, so that other lists on the site would use that class and look as defined. This one didn’t work for me, as my lists were coming from a content editable area, and so users wouldn’t know to add the style.

    Perhaps those will give you some ideas. Good luck.

    Copy & paste the code below to embed this comment.
  29. A Colleague saw this script on this site ages
    ago and sent it to me so that i could try and turn this into a vertical navigation but yet again it’s got bugs! as it doesn’t work properly in IE6 yet it does in all the other browsers that i have tried (can anybody help with this one!


    <html>
    <head>
    <title>Test CSS Vertical Navigation</title>
    <meta http-equiv=“Content-Type” c charset=iso-8859-1”>
    [removed]
    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. {
    this.className+=” over”;
    }
      node. {
    this.className=this.className.replace(” over”, “”);
    }
      }
      }
    }
    }
    window.
    [removed]
    <style type=“text/css”>
    ul {
      padding: 0;
      margin: 0;
      list-style: none;
    }
    li {
    position: relative;
    width: 160px;
    }
    li a {
    color: #FFFFFF;
    text-decoration: none;
    background-color: #939E7E;
    display: block;
    text-indent: 15px;
    font:  normal 12px/20px verdana;
    border-top: 1px solid #FFFFFF;
    width: 160px;
    }
    li a:hover {
    color: #284100;
    background-color: #D6DACD;
    display: block;
    width: 160px;
    }
    ul li ul {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
    margin-left: 160px;
    }
    li > ul {
    top: 0;
    left: 0;
    }
    li:hover ul, li.over ul {
    display: block;
    }
    li#last {
    width: 160px;
    margin-right: 0px;
    }
    li#last a {
    width: 160px;
    }
    #left {
    position: relative;
    top: 100px;
    left: 100px;
    }
    </style>
    </head>
    <body>
    <div id=“left”>
      <ul id=“nav”>
      <li>Main menu
        <ul>
          <li>Link 1</li>
          <li>Link 2</li>
          <li>Link 3</li>
          <li>Link 4</li>
          <li>Link 5</li>
        </ul>
      <li>Next menu
        <ul>
          <li>Link 1</li>
          <li>Link 2</li>
          <li>Link 3</li>
          <li>Link 4</li>
          <li>Link 5</li>
        </ul>
      </ul>
    </div>
    </body>
    </html>

    Copy & paste the code below to embed this comment.
  30. Hi,

    I’ve been playing around, trying to find some way of making the second level be displayed horizontally, and I’ve come to the conclusion that I can’t, at least, not with the Suckerfish and my knowledge of CSS… Any ideas? The problem is that the width of the parent li has to be wide enough to hold all the child lis, but narrow enough to be a tab. Maybe I could slide each tab across, so that they overlap, but then it needs to know which tab it is.

    Thanks,

    Will Thompson

    Copy & paste the code below to embed this comment.
  31. Thanks so much for this great tutorial! It’s a holy grail, that’s for sure.

    I’m using the menu system for a design in process, and I encountered something that should be noted for others who also wish to use this system.

    If your menu drops down over any element that is positioned relatively, the dropped down menu disappears behind that relatively positioned element in IE/6 Win, regardless of what z-index you give the menu.

    Thanks again! It’s awesome.

    Copy & paste the code below to embed this comment.
  32. You sholud give a higher z-index and relativ position to the parent element of your menu which is on the same level or higher then other positioned elements.

    [div id=“positionedelement” style=“position:relative;z-index:1”]
    [/div]

    [div id=“menu” style=“position:relative;z-index:2”]
    [ul][li]list1
    [ul]submenu[/ul]
    [/li][/ul]
    [/div]

    [div id=“positionedelement” style=“position:relative;z-index:1”]
    [/div]

    Copy & paste the code below to embed this comment.
  33. The menu doesn’t seem to work in Moz/Firebird/Net when you use the “overflow: auto;” css-style on the content below. If you hover over the links with these browsers, the menu hides when you move the coursor over the content below. In Explorer and Opera it works fine…

    Check it out:
    http://www.acc.umu.se/~caran/barebone.html

    I dont know if its a flaw in the code or the browser… Do you know?

    Copy & paste the code below to embed this comment.
  34. Ok so in the example, the first element in the list has a clickable region that is the entire box, not just the text. The ones bellow the first element in any of the drop downs, has a clickable region of only the text, is there a way to fix it so that all of the links in the drop down have a clickable region of the entire box and not just the text?

    Copy & paste the code below to embed this comment.
  35. Really like the menus, already got plans to implement them in one site, and will be keeping an eye on this site for the more drop down levels. That would make the script excellent.

    Will try and see if I can help out with that.

    Copy & paste the code below to embed this comment.
  36. My menu flickers in Netscape 6.2.3. It seems like the only solution here is to wait for browser updates. Has anyone found an answer to this problem yet?

    Dagmar

    Copy & paste the code below to embed this comment.
  37. The Suckerfish example doesn’t seem to work on Netscape 6.2.2 on MacOs9. Has anyone else experienced this? Is it just my machine or is it a problem with that version of the browser? Has anyone found a workaround?

    Copy & paste the code below to embed this comment.
  38. Previous comments have pointed out that there’s a big problem in Safari 1.0, although the dropdowns work fine in Safari 1.1 (apparently, Apple fixed the bug). From reading all the comments, the Safari 1.0 problem seems to be the worst issue with the menu.

    Here’s a workaround. This uses JavaScript to detect Safari 1.0, and keeps the second-level menu hidden from that browser only.

    Insert the following immediately above the </head> tag:

    [removed]<!—
    function BrowserDetect() {
    var ua = navigator.userAgent.toLowerCase();
    this.isSafari = (ua.indexOf(‘safari’) != – 1);
    this.versionMinor = parseFloat(navigator.appVersion);
    this.isSafari10 = ((this.isSafari) && (this.versionMinor < 87));
    if (this.isSafari10 == true) {
      [removed](’<style type=“text/css”>li li {display: none}<\/style>’);
    }
    }
    var browser = new BrowserDetect();
    //—>[removed]

    You could put the JavaScript in a separate file, of course, but the reference to it needs to be located after the CSS, in the <head>.

    I copied most of these lines of code from the Browser Detect script by Chris Nott, which is available under a Creative Commons license at http://www.dithered.com/javascript/browser_detect/

    Note that (1) the version number in Safari’s user agent string is the build number, not 1.0 or 1.1; and (2) I don’t know the correct number to use in the script. 87 may not be the best. All I know is that I’m using Safari 1.0.1 (with OS 1.2.8) and it is version 85.6. I don’t know what version was the first for Safari 1.1. (I didn’t see it in a quick look at Dave Hyatt’s blog.) If someone knows the answer, please post it.

    Using the above code, Safari 1.0.1 displays only the top-level menu with working links, while the dropdown menus work in other browsers.

    Copy & paste the code below to embed this comment.
  39. Corrections: The title of my post should have been “Safari 1.0 workaround” (not 1.1). And I’m using Mac OS X 10.2.8 (last Jaguar version).

    Also note that I’m not a JavaScript wizard, so someone may be able to improve the code.

    Copy & paste the code below to embed this comment.
  40. If someone has a vertical popup/“dropdown” menu that is ready for prime time, I’d love to see it; and use the code, if you’re willing to share.

    I’ve been trying to create a vertical version, where the second-level menus open to the left. After spending a couple days, including looking at a few prominent CSS sites for ideas (including Listamatic), I nearly succeeded, but have given up. From what I can tell, browser support is not good enough yet to implement this on a business web site for a paying client.

    Eric Meyer came close
    http://www.meyerweb.com/eric/css/edge/menus/demo.html
    But it only works in some browsers, and some important details are not so great (on mouseover, the menu “title” disappears from top-level menu). Not good enough for my needs.

    Given that a CSS-only solution is NOT ready for prime time, I would like to find a JavaScript substitute that meets ALA’s usual criteria: high-quality, high standards-compliance, lightweight, portable, customizable. Of course, it needs to work in nearly all browsers, especially IE/Win.

    Copy & paste the code below to embed this comment.
  41. Is there any way to link to an external stylesheet that will do the same thing? I’d like to use this IE hack, but I’m trying to keep my web pages clean.

    Copy & paste the code below to embed this comment.
  42. I have created left and right side vertical menus and a “drop-up” menu examples using :hover and my emulator behavior.
    No CSS hacks or additional elements, so you should choose your favourite one to make these basic functional menus perfect.
    Tested:Ie6Win/FireBird 0.7.

    http://www.hszk.bme.hu/~hj130/css/list_menu/hover/index.html

    Copy & paste the code below to embed this comment.
  43. Larry’s aforementioned code seems to grab the “spoofed” Mozilla version number (which is “5”) rather than the Safari build number.  As a result, using his code appears to disable the drop down functionality for all versions of Safari, not just the pre-Panther versions.

    I managed to cook up the following code which appears to grab the correct build number.  Note that Javascript is not at all my specialty, so some of you will undoubtably find “opportunities for improvement.”  :)

    // Sniff pre v.86 versions of Safari

    var agt = navigator.userAgent.toLowerCase();
    var appVer =  navigator.appVersion.toLowerCase();

    var is_safari =  (agt.indexOf(“safari”) != -1);
    var build =  appVer.substring(appVer.lastIndexOf(”/”)+1);

    if (build < 86) {
    [removed](’<style type=“text/css”>li:hover ul { display: none } </style>’);
      }

    Copy & paste the code below to embed this comment.
  44. Fixed a couple of problems for you and got it to validate.  I got it to work as (I think) you intended in MSIE 6.0, Netscape 7.1, Opera 7.23, Mozilla/Firebird 0.7, K-Meleon 0.8.2.  The main to the css changes were:

    li {

    Clear: left;
    float: left;
    }
    ul>li{
    clear: none;
    float: none;
    }

    li > ul {
    top: auto;}

    See: http://whistlingduck.wrellis.com/menu4.html

    I am still having issues with my site on Mac browsers.  Unfortunately I do not have easy access to a Mac so turnaround is slow.  If anyone has any advice I would sure appreciate it.
    -William Ellis

    Copy & paste the code below to embed this comment.
  45. URL for aforementioned site is:
    http://whistlingduck.wrellis.com/

    Sorry about that…
    -Will

    Copy & paste the code below to embed this comment.
  46. dont forget the doctype:
    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
    “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>


    i was using Transitional and it wouldn’t work in Mac/IE. once i changed to strict, everything worked great.

    Copy & paste the code below to embed this comment.
  47. I’m working on a website for school and my teacher refuses to give up frames.  He wants a drop-down menu in a typical side-bar fashion.  After trying this example, my drop-downs go outside of the frame so they aren’t much good.
        I was looking at two solutions, and was wondering if anybody here could help me with either of them.

    Solution 1:  Code the drop-downs in such a way so that the drop-downs push the lower options out of the way, in the same column.  Example(hope this works):

    Heading 1
    Heading 2
    Heading 3

    And when mouse hovers on Heading 2, you get:

    Heading 1
    Heading 2
      Option 1
      Option 2
    Heading 3

    You get the idea, right?

    Solution 2 (may be easier?):  His main objections to tables instead of frames is that it’s easier to maintain one menu file.  So, I was wondering if it would be possible to add in a special HREF that would embed the code for the menu into the table, without having to copy it again.  I hope you can understand what I mean…

    Thanks for the help, and I’m finding this to be a great site for information.

    Copy & paste the code below to embed this comment.
  48. Nice tutorial.

    Janos – awesome :)

    Copy & paste the code below to embed this comment.