GreatWebGuy Self-proclaimed greatness is a hard thing to prove.

21Feb/0813

Suckerfish DHTML dropdown menu with JQuery

DHTML dropdown menu's have been greatly improved in terms of accessibility, standards compliance, and weight using the Suckerfish technique of building pure CSS-based menus and then attaching a small javascript that allows Internet Explorer 6 to mimic the CSS hover method. Once the die-hards hanging onto IE6 let go, we won't have to worry much about this anymore, but for now it looks like it's going to linger for a bit.

I've been using JQuery for a bit now for all of my DOM manipulation and have found great savings in the amount of JavaScript code I have to write and the ease in which it can be employed in a CSS based site.

While this is generally the last piece to get IE working with your menu's, here's the JQuery code to replace the suckerfish Javascript, which is being used on this site now. If you're familiar with suckerfish, the JQuery code should be readable enough to figure out what's going on.

$(function() {
	if ($.browser.msie && parseInt($.browser.version)< 7) {
	    $("#tabs li").hover(
            function() {
            	$(this).addClass("sf");
            },
            function() {
		$(this).removeClass("sf");
            });
	}
});

The CSS code:

#tabs {
	background:transparent url(images/fade_grey_tab.gif) repeat-x scroll center bottom;
	margin:0;
	padding:0;
}
#tabs ul {
	display:block;
	position:absolute;
}
#tabs ul.children {
	margin:0;
	padding:0;
	border-top:1px solid #FCD290;
	z-index:100;
	visibility:hidden;
}
#tabs li {
	background:#969696 url(images/bg_grey_tab.gif) no-repeat scroll left top;
	display:inline;
	float:left;
	height:auto;
}
#tabs li li {
	background:#FFF0CE none repeat scroll 0%;
	display:block;
	float:none;
}
#tabs a {
	text-decoration:none;
	background:transparent url(images/bg_grey_tab.gif) no-repeat scroll left top;
	border-right:1px solid #A2A2A2;
	color:#FFFFFF;
	display:block;
	font-weight:bold;
	line-height:20px;
	text-align:center;
	width:115px;
}
#tabs a:hover, #tabs a.selected {
	background:#FCDA2E url(images/bg_orange_tab.gif) no-repeat scroll left top;
	color:#FFFFFF;
	text-decoration:none;
}
#tabs ul a {
	background:#FFF0CE none repeat scroll 0%;
	border-bottom:1px solid #FCD290;
	border-left:1px solid #FCD290;
	border-right:1px solid #FCD290;
	color:#666666;
	line-height:20px;
	width:115px;
}
#tabs ul ul a {
	background:#FFF9EA none repeat scroll 0%;
}
#tabs ul a:hover, #tabs ul a.selected {
	background:transparent url(images/bg_orange_tab.gif) no-repeat scroll left bottom;
}
#tabs li:hover ul, #tabs li.sf ul {
	visibility:visible;
}
#tabs li:hover ul ul, #tabs li.sf ul ul {
	visibility:hidden;
}
#tabs li:hover ul, #tabs li li:hover ul, #tabs li.sf ul, #tabs li li.sf ul {
	visibility:visible;
}

The markup, slimmed down version of my menu, only the necessities:


I'm putting this post out there for Javier, who reads my blog, but doesn't understand a word of it, and the answer to that burning question is, no my wife won't let me date that girl from work ;)

Comments (13) Trackbacks (0)
  1. Nice article, and thanks for the comment on my blog as well. I’ve been a big fan of Suckerfish, and of course I like to see the JS fix being implemented by jQuery.

  2. Awesome! Great article very nice, this would be very useful codes to implement dropdown menu using css and a little bit of jQuery…. tnx a lot

  3. Thanks for the code, It helped me fix a Z-index bug.

  4. Is there a way one could use an image w/ a rollover state for the main menu item, that would stay ‘on’ while the drop-down was open? I have a menu with different-width nav items and rollover stated. Strangely, I am finding it hard to find a solution.

    thanks!

  5. Somehow the menu on top does not seem to do anything when I put my mouse over it… dud you remove the functionality?

  6. @Sajal yeah, sorry about that, site has been redone since this post was written.

  7. A bloody demo is too much, a?

    • It’s not enough I write the code for you, you want me to implement it too? WordPress doesn’t particularly like me inserting javascript and css in the middle of a post, so until I feel like setting up a site just dedicated to demos, nope no demos…

  8. I understand that this correctly makes a slider:
    $(function(){
    $(’select#focusSel’).accessibleUISlider({width: 800, labels: 11});
    });
    Also, this correctly writes a cookie when a select is changed:
    $(document).ready(function(){
    $(’#focusSel’).change(function() {
    $.cookie(’focus’, $(this).val()); // set cookie
    Though, I find no way to let the slider write a cookie. I tried this:
    $(document).ready(function(){
    $(’#focusSel’).accessibleUISlider({width: 800, labels: 11}).change(function() {
    $.cookie(’focus’, $(this).val()); // set cookie
    but oddily, while the slider is created, the cookie is set *only* if I use the select, and not if I use the slider. They seem coupled, in that the select is updated when moving the slider, in fact they are not, as the cookie is not set.
    Please, what should I write to have the slider write a cookie?
    I have been trying for days but cannot imagine a solution.
    Thanks!

  9. @Ecstrim

    Dude, it takes fifteen seconds to implement.

    Thanks for the script. Any suggestion on keeping the parent cell background colored while the cursor is over the children?

    Thanks again!

    • @Bennet The hover should be on the li that surrounds that entire menu section meaning that li can be targeted with a hover selector to affect it during the hover ul.topnav li:hover {color:#fff} just as an example. Hope that helps.

  10. Do you have the images handy so I can complete the demo? Thanks.


Leave a comment

(required)

No trackbacks yet.