Suckerfish Style Menus in Drupal 6.x
I spent hours and hours hunting around for a simple solution to implementing suckerfish-style drop-down menus in Drupal 6. Lo-and-behold, I couldn’t find one. Every solution out there was overly complicated, and didn’t quite do what I wanted it to.
After a few hours of hacking around, this is the solution I came up with.
First I started up by setting up my menu structure. I went to Administer >> Site building >> Menus >> Primary Links, and set up my menu, setting up all the appropriate pages and their sub-pages directly beneath them. That was the easy part. Now for the rest…
First I setup my ’suckerfish’ functions. I found a script online that emulated suckerfish style behavior using jquery. Since jquery is already built in to Drupal, this was easy enough to implement.
dfn_menus.js
-
-
/* Emulates Suckerfish-style functionality with JQuery */
-
/* Adds animation effect for drop-down and fadeups */
-
-
$(document).ready(function(){
-
$("#dfnmenu li").hover(
-
function(){ $("ul", this).fadeIn("fast"); },
-
function(){ $("ul", this).fadeOut("fast"); }
-
);
-
if (document.all) {
-
$("#dfnmenu li").hoverClass ("sfHover");
-
}
-
});
-
-
$.fn.hoverClass = function(c) {
-
return this.each(function(){
-
$(this).hover(
-
function() { $(this).addClass(c); },
-
function() { $(this).removeClass(c); }
-
);
-
});
-
};
-
Once thats done and saved, we also need to create a style sheet. I’ll paste mine here as a reference. You may want to change it to suit your preferences. Disclaimer: I chopped it up and removed bits that were not needed, since they applied to the theme and skin that I had applied. I may or may not have left remnants and/or removed something I shouldn’t have.
dfn_menus.css
* UPDATED 2009.02.17
-
-
-
/* Navigation */
-
.menu ul, .menu ul li ul {
-
list-style: none;
-
margin: 0;
-
padding: 0;
-
}
-
-
.menu {
-
z-index: 10;
-
position: relative;
-
text-align: left;
-
width: 800px;
-
height: 33px;
-
}
-
-
/* TOP LEVEL MENU ITEM */
-
.menu ul li {
-
float: left;
-
margin: 0;
-
padding: 0;
-
position: relative;
-
}
-
-
/* TOP LEVEL MENU ITEM */
-
.menu ul li a,
-
.menu ul li a:link,
-
.menu ul li a:active,
-
.menu ul li a:visited {
-
font: 1.1em/27px Verdana;
-
color: #555555;
-
display: block;
-
padding: 1px 34px 0px 34px;
-
margin-top: 1px;
-
text-decoration: none;
-
border-left: 1px solid #ddd;
-
outline: none;
-
}
-
-
/* Make sure the first item in the list doesnt have a left border */
-
.menu ul li.first a {
-
border-left: 0px;
-
outline: none;
-
}
-
-
/* TOP LEVEL MENUS ITEMS ON HOVER */
-
.menu ul li:hover a,
-
.menu ul li.sfHover a,
-
.menu ul li a:hover {
-
background-color: red;
-
background-position: -15px -33px;
-
height: 30px;
-
outline: none;
-
}
-
-
/* SECOND LEVEL MENU ITEM */
-
.menu ul li:hover ul li a,
-
.menu ul li:hover ul li a:visited,
-
.menu ul li.sfHover ul li a,
-
.menu ul li.sfHover ul li a:visited {
-
font-weight: normal;
-
color: #666666;
-
background:#e8f0f3;
-
margin: 0px;
-
border: 0px;
-
outline: none;
-
height: 23px;
-
padding: 0px 34px 3px 34px;
-
}
-
-
/* SECOND LEVEL MENU ITEM HOVER */
-
.menu ul li:hover ul li a:hover,
-
.menu ul li:hover ul li.first a:hover,
-
.menu ul li:hover ul li.last a:hover,
-
.menu ul li.sfHover ul li a:hover,
-
.menu ul li.sfHover ul li.first a:hover,
-
.menu ul li.sfHover ul li.last a:hover {
-
height: 23px;
-
background: #FFFFFF;
-
padding: 0px 34px 3px 34px;
-
color: #000;
-
width: auto;
-
}
-
-
/* SECOND LEVEL MENU ITEM */
-
.menu ul li ul {
-
width: 200px; /* expand as needed for longer submenu names */
-
color: #000000;
-
list-style: none;
-
margin: 0px;
-
padding: 0px;
-
position: absolute;
-
top: -999em;
-
left: 0px;
-
border: 1px solid #dddddd; /* border around dropdown menu */
-
opacity: 0.9;
-
-moz-opacity: 0.9;
-
}
-
-
.menu ul li:hover ul, .menu ul li.sfHover ul { top: 30px; }
-
-
.menu ul li ul li {
-
border: 0px;
-
float: none;
-
padding: 0px;
-
margin: 0px;
-
color: #000000;
-
}
-
-
.menu ul li ul li a {
-
border: 0px;
-
white-space: nowrap;
-
float: none;
-
padding: 1px 34px 1px 15px;
-
margin: 0px;
-
display: block;
-
height: 29px;
-
color: #000000;
-
}
-
-
.menu ul li ul li a:visited { color: #000000; }
-
-
.menu ul li ul li a:hover {
-
background: #CEFFCE;
-
color: #000;
-
border: 0px;
-
margin: 0px;
-
}
-
Once you have both of those files saved into place, now its time to make the magic happen. Now navigate to your theme folder, wherever it might be (usually something like /sites/all/themes/) and open your page.tpl.php file. This is where we make our changes.
First we include our css and js files. Add the following somewhere in the head section:
page.tpl.php
Once that’s done, we actually have to make the menu print out. This is the way I did it. I commented out the line that prints the $primary_links variable, and replaced it with this:
page.tpl.php
-
-
<div id="dfnmenu" class="menu">
-
<?
-
$my_menu = menu_tree(‘primary-links’);
-
$my_menu = str_replace("leaf", "", $my_menu );
-
$my_menu = str_replace("active-trail", "", $my_menu );
-
$my_menu = str_replace("menu", "", $my_menu );
-
$my_menu = str_replace("active", "", $my_menu );
-
$my_menu = str_replace("expanded", "", $my_menu );
-
$my_menu = str_replace(" class=\"\"", "", $my_menu );
-
print $my_menu;
-
?>
-
<div style="clear: both;"></div>
-
</div>
-
What this does is loads the menu tree, and then strips out all the extra stuff I didn’t need, liks classes and id’s and the like – I just wanted the nested unordered lists. Once that’s done, it prints out the results. And that’s it. Simple right?
This may and most likely will require lots of css tweaking on your part. But its a solution that has worked for me, and hopefully will lead you in the right direction! Tested with Firefox 2+ and IE7. May or may not work well with older browsers.
Happy Coding!
~ digifuzz
Posted on Friday, June 13th, 2008 at 10:11 am and is filed under Drupal, Javascript, Php. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
June 23rd, 2008 at 4:26 am
Thanks, digifuzz for this coding help. Works great in IE and FF but won’t show at all in Opera. Is there a fix or hack for Opera?
June 23rd, 2008 at 5:16 pm
Hey Linda, I didn’t test it on Opera, but after some quick googling, I read that suckerfish style menus in opera are a bit quirky, specially if you don’t set a specific width to the li’s. So just for kicks, try applying a “width: 150px;” or whatever suits you better to the top-level li’s.
/* TOP LEVEL MENU ITEM */
.menu ul li {
float: left;
margin: 0;
padding: 0;
position: relative;
width: 150px;
}
I’ll do a little testing soon and let you know what I come up with.
~ digifuzz.
June 24th, 2008 at 5:37 am
Tried a width change and clear: both. Nothing changed. I’m considering changing to another CMS. Unfortunately.
June 24th, 2008 at 8:11 pm
Hmm, strange. I tested it in Opera, and – besides being placed a few pixels below where it displays on the other browsers – it seems to work fine. If you haven’t already completely ditched Drupal, could you explain exactly what does happen in your browser?
~ digi
July 20th, 2008 at 9:57 am
I got this working perfectly with some quick CSS tweaking, but my question i’m stumped on.. it makes my Primary Links work beautifully but then when logged in as Admin my navigation links in my left blocks go all messed up and wreck the page.
How can I make this ONLY implement for the Primary Links and ignore all other menus?
Cheers.. thanks for putting this out there, been messing with it for a few weeks now and I finally feel like i’m nearly there!
July 22nd, 2008 at 8:07 pm
Hey, nice work!
I’m having a little difficulty implementing it with the Zen theme though. I notice in the js code you refer to #dfn css styles which are not (no longer) in your css file.
Did you take those out when you were editing?
Also i saved my js and css files into my subtheme folder and just added the following code to the top of the template.php:
drupal_add_js(path_to_theme().’/myMenus.js’, ‘theme’);
and this to the .info file:
stylesheets[all][] = myMenus.css
I believe this is better for using with a subtheme? I’m new to Drupal =P
Have you tried decoding whatever Roople Themes is doing with their templates? Maybe i should just get one of their themes and edit it.
I can’t believe that there isn’t a suckerfish drupal module…
Thanks
July 22nd, 2008 at 8:12 pm
Bah, my bad, i see it where you put it in the page.tpl.php coding.
Could you maybe clarify where exactly that should go?
This is what i’ve got:
I must have not entered it correctly.
Thanks again!
August 4th, 2008 at 9:04 am
Hi diggifuzz,
Thx for sharing your code,
I have seen that the roople themes use a version of suckerfish:
http://demo.roopletheme.com/
August 6th, 2008 at 10:36 am
Ya i ended up modding a the litejazz roople theme to get my suckerfish menus to work.
August 8th, 2008 at 4:54 pm
Sorry I haven’t answered any of your questions as of late. Family has been demanding my time tons, which is not a bad thing, as far as I’m concerned.
@sen: Wrap your primary_links in a div with a unique class, and change your suckerfish related css to apply to only elements within that div.
@Suckfish & Nico: I have actually looked at the roople themes in the past (specifically the tapestry theme), and while it had the desired end-results, it required more region and block creating and I decided I wanted to try to use suckerfish without having to do all that. Call it a personal challenge, etc. It’s always fun to see how many different paths one can take to reach the same happy ending.
August 26th, 2008 at 4:40 am
I have been using a module called nice_menu’s in Drupal, but for some reason I can’t get the drop downs working in IE6. FF / Safari / Opera are no problem.
Seems like the JS isn’t working.
I’m wondering though, why can’t drupal just output menu’s as nested ul, li’s?
It seems you need major work-arounds just to get this to work.
August 26th, 2008 at 5:09 pm
Yeah, I don’t know. The simplest way I could get Drupal to output the lists as nested ul/li’s is as shown above in the page.tpl.php section. If there is a simpler way, I’d love to hear about it.
~ digifuzz
October 31st, 2008 at 6:10 am
Great work, exactly what I was looking for – just a quick question though. How would I output the nested unordered list for a menu other than the primary links? I’ve tried changing the reference in:
<?
$my_menu = menu_tree(‘primary-links’);
…etc
to
<?
$my_menu = menu_tree(‘new-menu’);
…etc
where ‘new-menu’ is the machine-readable name of my custom menu, but nothing prints out. What am I missing?
(I can’t use primary links because the site I’m working on is a “virtual site” within a larger drupal installation. Using ‘primary-links’ works fine (ie. prints out the menu nicely) but doesn’t link to the menu I want!)
Keep up the good work!
November 17th, 2008 at 3:24 pm
Hi,
I am using the salamander theme and trying to follow your steps to setup the suckerfish menu, and I got stuck in where I need to replace the $primary_links with the div you have listed above. Here is my content of the page.tpl.php. Would you please before specific on how I replacing the code. Thank you so much for your help.
<html xmlns=”http://www.w3.org/1999/xhtml” lang=”language ?>”
xml:lang=”language ?>”>
<meta name=”language” content=”language ?>” />
$(document).ready(function(){
$(document).pngFix();
});
<a href=”"
title=”">
<img src=”"
alt=”" id=”logo” />
<a href=”"
title=”">
<td class=”section “>
<td class=”section “>
<td class=”section “>
0): ?>
<td class=”section “>
<td class=”section “>
<td class=”section “>
‘links’, ‘id’ => ‘navlist’)) ?>
Copyright © All right reserve
November 17th, 2008 at 3:26 pm
Didn’t seems to have all the code copied. ;( try again.
<html xmlns=”http://www.w3.org/1999/xhtml” lang=”language ?>”
xml:lang=”language ?>”>
<meta name=”language” content=”language ?>” />
$(document).ready(function(){
$(document).pngFix();
});
<a href=”"
title=”">
<img src=”"
alt=”" id=”logo” />
<a href=”"
title=”">
<td class=”section “>
<td class=”section “>
<td class=”section “>
0): ?>
<td class=”section “>
<td class=”section “>
<td class=”section “>
‘links’, ‘id’ => ‘navlist’)) ?>
Copyright © All right reserve
November 17th, 2008 at 3:27 pm
When I pasted the code in the box, I saw everything, but majority of the code disappeared right after I submitted. :_(
November 22nd, 2008 at 12:50 pm
[...] author of the other technique who’s article I am too lazy to find at the moment (oh alright, heres his technique but mines still smooth as silk y0) and whos code for modifying the menu output was used as a basis [...]
December 5th, 2008 at 9:28 pm
What could I possibly be doing wrong here????
Here is the link to the site.
Any help would be greatly appreciated.
shereewhitfield.com/go
December 6th, 2008 at 8:44 am
Anyone have trouble with IE6?
The main menu shows, but no submenus.
December 9th, 2008 at 12:02 pm
@Kevin:
You need to comment out the comments you added in your javascript functions. For some reason, most modern browers i checked it in simply assumed it was a comment and proceeded as usual.. ie6 dies there.
this is the part that you need to properly comment out:
January 14th, 2009 at 8:34 am
Thank you thank thank you! I was getting so frustrated trying to find a simple solution.
January 15th, 2009 at 8:22 am
@Becky: Glad you found it useful!
January 16th, 2009 at 1:56 pm
Me again! How would I go about setting a different ID for each ? I know its this line but I’m not sure what to put (see ???):-/
$my_menu = str_replace(“menu”, “???”, $my_menu );
January 29th, 2009 at 12:05 pm
@Becky,
I’m not sure, I haven’t been working with any Drupal sites @ work lately, so I haven’t had a chance to play around and figure it out! But, if you happen to figure it out on your own, I’d be interested in what you did!
February 9th, 2009 at 1:24 pm
in case anyone else is banging their head against the keyboard getting this to work, there are some missing commas in the css. for instance:
/* TOP LEVEL MENUS ITEMS ON HOVER */
.menu ul li:hover a, .menu ul li.sfHover a .menu ul li a:hover {
should be
/* TOP LEVEL MENUS ITEMS ON HOVER */
.menu ul li:hover a, .menu ul li.sfHover a, .menu ul li a:hover {
nothing inside the menu has the class menu, only the container…
February 12th, 2009 at 5:07 pm
I have been hunting around for this solution for days for the new site I am building thanks alot. I think you just saved me many hours of stress. I was bout ready to burn a picture of a small woodland creature over my computer
February 17th, 2009 at 11:12 am
@shampton,
OMG hey, I have no idea how I over-looked those commas! Thanks for spotting that, the css has been updated.
February 17th, 2009 at 11:17 am
@Okinawa Guy,
I’m glad no pictures of small woodland creatures had to be sacrificed over your computer because of me.
March 1st, 2009 at 11:23 am
Hurray! This works exactly perfect. Not only does it work perfect, but it works 100% as a drop in replacement once the css file you added is taken out. I like the opacity and I might include it in my own css file, but I think I like exactly how it is without any additional things attached.
This guide was not just very simple and to the point, it got me exactly to the goal I was after.
Consider yourself bookmarked.
March 4th, 2009 at 2:00 pm
@MTecknology: Awesome, thanks
March 9th, 2009 at 10:41 am
Awesome dude! Many thanks! U saved me a lot of trial and error
March 12th, 2009 at 7:56 am
@Eddy: Sure thing. Nice blog, btw.
March 13th, 2009 at 2:00 am
Thank you so much for this! I’ve been trying to figure this out for two days now. Finally! Blessings to you.
July 27th, 2009 at 11:18 am
Thanks so much! This script is awesome! Still working out the IE6 and IE7 kinks, though
July 27th, 2009 at 2:43 pm
Hey,
I followed all the directions but, am still having some problems.
First, the menu doesn’t expand on mouse over.
Second, when I click on the menu item, and it does expand, the entire menu moves up on my page.
Third, the “child” item gets a created link in the upper right hand corner of the page when the items expand.
Any ideas?
August 5th, 2009 at 1:36 pm
Works great on my test site except I have the same problem as #5 above. I don’t understand your answer in #10
@sen: Wrap your primary_links in a div with a unique class, and change your suckerfish related css to apply to only elements within that div.
I think I did the top one but which css sheet do i change to my new div? The one you had us create or the style sheet for the theme?
Lost as usual,
- Don
August 5th, 2009 at 1:54 pm
Ignore above (36)… I took a few wild guesses and figured out how to do it… (rather lucky really, just compared the theme’s existing css sheet)
This really is a great way to do pulldowns. Thank you for posting it!
August 6th, 2009 at 12:40 pm
Not sure if you reply often but I thought I’d ask (yet another) question that has been perplexing me. How would you do more than one level of drop down menus?
Cheers
- D
August 6th, 2009 at 1:06 pm
This is the greatest site in the world. I beat my head into a wall trying to figure out something, give up and ask for help here… only to figure it out myself ten minutes later.
Twice now!
August 25th, 2009 at 12:31 pm
@Don: Hey, sorry, it’s been a while since I’ve come around – life does that sometime, right? Glad you figured it out!!
November 2nd, 2009 at 4:57 am
[...] Suckerfish Style Menus in Drupal 6.x Credit: digifuzz [...]
November 4th, 2009 at 11:37 pm
Commenting commonly is not my thing, but ive surfed an hour on the blog, so thanks for the info .
November 19th, 2009 at 11:56 am
@debra: Why awful info?
December 29th, 2009 at 12:10 am
how do i make a: active link in the sukerfish menu
please help me out its urgent
January 4th, 2010 at 9:28 am
thanks, this helped a lot! This saved me time instead of having to switch to a ROople theme. A lot of the menu css seems like extra but it’s not hard to tailor.
January 8th, 2010 at 12:47 am
Hi i am new to drupal… I have done every step which are mentioned in this page but when i visit the page, a javascript error occurs
$ is not defined
$.fn.hoverClass = function(c) {\r\n confiztestjs.js (line 1)
confiztestjs.js (line 1)
March 6th, 2010 at 8:53 am
Asim: looks like maybe you aren’t properly loading jQuery?