background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount

Suckerfish CSS Drop Down Menus in Drupal Made Simple

Eric.London's picture

In this article I'll explain how to implement drop down menus in the easiest way possible. Before I begin, please checkout the original "suckerfish" dropdown tutorials like: A List Apart and Son of Suckerfish Dropdowns. Unfortunately, most CSS drop down tutorials still require you to add javascript to resolve IE6 issues. CSS menus require the ":hover" attribute on LIs, and IE6 just can't handle it. I figured since Drupal already includes jQuery, I'd write a tutorial that takes advantage of jQuery's simplicity and keeping the CSS to a minimum for ease of maintenance.

The first thing I did was create my menu structure. For this tutorial to work, you'll need to ensure all the menu items are set to expanded (which makes sure they are all rendered when the menu is sent to the theme layer).


For purposes of this tutorial, I create a very blank theme (I started off use Garland, but I wanted to keep the CSS generic). I assigned the menu block (primary links) to a region on my page:


Next, I added the following CSS. As you can see, I'm using the unique identifier on the primary link block in this example. Check out the CSS comments to better understand what each line of CSS does. This CSS works with any number of child menus. NOTE: If you wanted your menus to scale with the font size, you could replace all the measurements with "ems".

/* remove any previously set margins and paddings */
#block-menu-primary-links * { margin: 0; padding: 0; }

/* set width/height on <li>, <a>, <li><ul> */
#block-menu-primary-links li ul,
#block-menu-primary-links li,
#block-menu-primary-links a { width: 125px; height: 25px; }

/* remove <li> list styling off */
#block-menu-primary-links li { list-style: none; }

/* display <a> as block */
#block-menu-primary-links a { display: block; }

/* set <li> position */
#block-menu-primary-links li { float: left; position: relative; }

/* set position of <ul> in <li> */
#block-menu-primary-links li ul { top: 25px; left: 0px; position: absolute; }

/* position child <ul> */
#block-menu-primary-links li ul ul { margin: -25px 0 0 125px; }


For demonstration purposes, I left off one very import line of CSS to show the new layout of the menu structure. As you can see, the LIs are now positioned vertical their parent, and the child ULs are positioned off to the right. I wanted to show all the menu items in their desired layout to give you the opportunity to adjust the CSS (height, width, padding, etc).


Now, you can add the last line of CSS which hides the display of all the child ULs:

/* set visibility of <ul> in <li> */
#block-menu-primary-links li ul { display: none; }


The previous line of CSS will leave you with just the top level menu items:


Lastly, I added a hover jQuery function to attach a javascript hide/show event on every LI:

$(document).ready(function(){
  $('#block-menu-primary-links li').hover(
    function(){
      $('ul:first', $(this)).show();
    },
    function(){
      $('ul', $(this)).hide();
    }
  );
});


Here's an example of what the final result will look like. If you implement this code, and mouseover the menu structure, the child ULs will appear and disappear.

How to make work for iphones, ipads

Hello. Any ideas you can provide as how as to how we can make this work on iphones/ipads since they don't support the hover functionality? The menu would have to show up upon click, instead of on hover on iphones/ipads. Your time and help are much appreciated. Thank you.

Thank you, thank you, thank you

You have saved my sanity. By posting this gem, you have earned big Karma points in the universe. This is exactly what I was looking for -- the least code to do these kinds of menus in the context of Drupal.

I am eternally grateful!!

Peggy

Works only when current item is selected

Thanx for tutorial, but it works only when current item is selected:
For example i have Primary links with items "About Us" "Our Creatures" and "Help"
The item "our creatures" have other 3 subitems. They appear only when "Our creatures" is still selected and i hover mouse on it. When i'm at "Help" for example, the hovering on "Our creatures" doesn't give results. How can i modify js to correct it?

V.F.

That's so great!!!

Thank you very much for this very useful and well done tutorial.
I have just some question: I'd like to change the color of a link when the mouse is on it. do somebody know the trick?
Otherwise in addition to the code above I added "#block-menu-primary-links li :hover;" in my pages.css to display the sublinks of the menu.

Mathilde

IE 6 drop down issue

Thank you for posting this, I am using it on a new Drupal site I am working on... There is one small issue, when I test in IE 6 the drop-down appears, but as I move the mouse down into the first drop-down link, they re-arrange themselves horizontally. As you move the mouse down through the drop-down menu, the links sometimes arrange themselves back as intended.

Have you ever run into this?

jquery function

Where do I add the jQuery function? I'm new to Drupal.

Thanks,
Melanie

Eric.London's picture

theme script.js

You can put it in your theme's script.js file. see: http://drupal.org/node/171205#scripts

Thanks a lot...but...

I tried on my new theme and it works fine. Don't forget to add to page.tpl.php or the menu will not show on mouseover.

But there is a problem. maybe just a little pity. I have a background color defined in css of a:hover on, let's say "menu-01", according to the demo image above. But when the pointer moves on the shown menu, let's say move on the "menu-01-01", the background color of "menu-01" changes back to a:link.

I think it's better to have the background color of "menu-01" the same as "menu-01-01" when the pointer is on it. How can the "menu-01" background color maintain a:hover definition when the pointer moves on the shown dropdown menu instead of changing back to a:link style?

thank you so much.
best regards.

I can't thank you enough!

I've been messing with nice menus for two days, not getting anything out of it. Then I find this and everything works flawlessly in 5 min!

1 million thanks!

Second level dissapearing when i mouse over it

Hi there, thanks for this tutorial - i have most of it, when i mouseiover the top level item it displays the flyouts, but when i mouseoveer the flyout, it dissapears.
I am not an expert coder, so please can you assist me to get it working.

thanks.

Many Thanks

Your generous contribution has helped me immensely and it also works fine with all major IE versions.

Thank you.
Hayesha

Only In Block?

I've noticed that the functionality stops working if I add the primary menu to my page.tpl.php ... does this HAVE to be in a block?

I'd like to be able to add it as the default menu within my page.tpl.php

What say you?

I'm going to pull my hair out...

I've got the menu implemented... not a problem at all. Great tutorial...but I cannot, for the life of me, stylize this menu one bit! Sure, I can tell various aspects of the menu items to be a different color, etc... but I'm trying to get a background image that spans the width of the site, and then load rollover images on top. My theme hates me. I'm using my own sub-theme of Genesis and I cannot understand what the deal is.

nice code - IE6 problem?

hi! I just put in the code into drupal 6.x and its working very nicely in everything except IE6. I have a horizontal menu bar with drop downs, but in IE6, it gets split in half into 2 rows? I've messed around with it, and now it's each menu item on a row. I'm not sure what's going on though..

Great tutorial

Thank you for the simplest, fastest menu ever!

Dropdown not working on inner pages

Hey Eric - Great tutorial. Thank you. I had been searching for a solution for this for a couple days now. I'm having one issue, it works great on my homepage - but doesn't work at all on any inner pages.

The jQuery is included on all the pages and the markup seems identical, but the java isn't enabling the display:block; on my li tag. The site is http://dev.ifxonline.com/. Any help would be much appreciated.

Best,

Michael.

Suckerfish for secondary links

Hi Eric

Thanks for the info and I've one question about suckerfish

How to put suckerfish in secondary link?
Any tutorials for that.

Thanks..

Only top level menus

I thank you for the tutorial, I enjoyed following it and working along.
Unfortunately I am only getting the top level menu. I have viewed the
source with Firefox and verified that the javascript file and the menus
are the full menu is in the code. The javascript is being loaded in the
code but only the top menu is being inserted into the code. Even though
I have set it to enabled and expanded. I have even deleted the whole
directory where drupal is and started over fresh, installed a few modules
(they are installed but not configured yet only thing that is configured
is the site information, which is development, this is also a brand new
theme that is being created from scratch that is only about 15 lines or so)
I am trying to do this for primary-links I think I have done everything
right but mine is not working. I added a Home menu and the rest are the
default drupal menus (Home, My Account, Create Content, Logout) with the
menus I have the only one that should have child menus is Create Content
which would have a Page and Story menu, I even tried adding the Administer
menu and expanding some of the child menus but it does the same thing.
No idea if it a module I have installed conflicting or not even though
they are not configured but the list of modules I currently have installed
are auto_nodetitle, captcha, devel, fivestar, logintoboggan, pathauto,
remember_me, token, views, votingapi. Any help you could shed on this
matter would be greatly appreciated.

thanks for this code

hi
thanks for this code .

i use this code in site : www.alphaomegachemicals.com you can see it.

umesh
www.raipurlive.com

Only see drop downs when logged in as admin

Hi there,

I've got your drop downs to work, however they are only appearing when I'm logged in as the administrator. I've checked the source code and the links are all in the source code, it seems the javascript part does not display them for other users.

I put the javascript at the head of the page.tpl.php page.

Any help much appreciated.

Ben

Eric.London's picture

view source

Hi Ben,

Have you been able to verify that the CSS and jQuery are loaded on every page by viewing the source?

Only getting first level menu items

Hi, thanks for the great tutorial. I am trying to follow, but I can't get my menu to print anything other than the first level of primary links. I have all of the menu items listed and checked as enabled and expanded. My theme uses print theme('links', $primary_links, array('id' => 'member-topnav')); to print the menu.

Do I need to add another paramter to tell it to show the second level or something? Any ideas?

Thanks for your help,
Nancy

It seems that the deeper

It seems that the deeper level only show up if you use the primary-menu in a block...

Eric.London's picture

yes

Yes, if you want to use this without having your primary links in a block, you'll have to update the CSS and jQuery selectors. Checkout this comment lower on this page:

http://ericlondon.com/suckerfish-css-drop-down-menus-drupal-made-simple#...

Eric.London's picture

expanded?

Hi Nancy,

Are your menu items set to expanded?

-Eric

Almost got it

Hi,
I've been scowering the web to find out how to achieve something that i thought would be simple and obvious and your little tutorial has got me the closest yet to the solution - thanks! I just need one further push. I'm not a coder, i can usually spot and edit simple stuff in style sheets etc and my copy-and-paste skills are tremendous so please keep that in mind :)

I got the tutorial to work - got the primary menu to work in a region block. However, i want it to work in the default primary links position - where it's already themed. I think you mentioned it in a reply about using ID's and passing a third argument, but i have no idea what that means?
Here's my site, it's very basic as i'm slowly learning the bits of Drupal i need to create what is essentially a good, clean, usable community site:
http://northbroads.villagelifeonline.co.uk/
I've put your tutorial menu at the bottom of the content for now and you can see it works. What i want is to have the drop down functionality on the menu at the top. If you could help with that - point me to the file to edit and what to paste in there - that would be fabulous! Assuming that's possible :)

Thanks
Robin

Eric.London's picture

ul.links.primary-links

Hi Robin,

If you'd like this to code to apply to the primary links, you'll need to change the unique identifier being used. In the sample code, I used "#block-menu-primary-links" because I chose to use a menu block. If you're using Garland (the default theme), the primary links are enclosed in "ul.links.primary-links". I recommend using the Firefox plugin called FireBug, it will help you identify elements of your HTML document. Try replacing "#block-menu-primary-links" with "ul.links.primary-links" throughout the code.

Hope this helps.
-Eric

Thanks for this post

What a great write-up of how to make this happen. I was searching and searching on how to add this functionality easily to the theme I was using. Your explanation makes sense and is simple to implement. Great job.
I also looked as Nice Menus module, but I didn't feel I should need a module to do what you could do with css and javascript. This will make it possible to add suckerfish functionality to any theme I want to use. Awesome.
Question for you, where do you recommend putting the javascript that you are adding in? The script.js file in your theme?

Eric.London's picture

glad to help

Thanks for the flattering comment!

Yes, the script.js is automatically included in Drupal 6 so it's a good place for the javascript.

hi! sorry i really don't find

hi!

sorry i really don't find where i've to put this javascript.. i've no file called script.js.
or what do you mean to put it directly in drupal 6?
thanks a lot for helping!
jule

Eric.London's picture

sorry

Hi Jule,

Sorry if I am lacking in detail department. If you decide to build this into your theme, you could create a file in your theme directory called "script.js", which will automatically be included.
http://drupal.org/node/171205#scripts

If you wanted to build a module out of this code, you could use the drupal_add_js function to include the code.
http://api.drupal.org/api/function/drupal_add_js

Hope this helps!
-Eric

trying to figure out the jquery code include

Hi Eric,
Thanks for the help - I read the provided links about including the js and this is what I added to my page.tpl.php file's :
<?php
drupal_add_js (
"$(document).ready(function(){
$('#block-menu-primary-links li').hover(
function(){
$('ul:first', $(this)).show();
},
function(){
$('ul', $(this)).hide();
}
);
});", 'inline');
?>

The div's aren't getting set as visible so Im not seeing the submenu's appear when I hover. What am I doing wrong? Thanks for the help!

Eric.London's picture

hmm

Have you verified that the correct jQuery is being shown in the page source?

a dumb question

Hi Eric:
Thanks for you sharing this idea, I tried to setup your code with a test page, and it worked without any problem (the dropdown worked just fine), my problem now is how to implement it in my menu. As far as I know (sorry I'm new to this), I need to put the id in the ul of my menus, so how/where do I do that? I've done everything you mentioned in your document: make all the menu items enabled and expandable, but I also need to add the id, but I don't know where to add this id.
ps: I'm using Zen theme

Thanks
Michael

Eric.London's picture

not a dumb question

Hi Michael,

In my tutorial, I added the menus and then assign the menu block to a region, which will come with a CSS identifier (#block-menu-primary-links). If the primary links are called directly in the theme using the theme() function, like this:

<?php
print theme('links', $primary_links);
?>

...you can pass a third argument to the theme() function containing attributes, like a class or id. For example:

<?php
print theme('links', $primary_links, array('id' => 'MYID'));
?>

Hope this helps!
Eric

getting the complete list of primary links

Hi Eric,

I went through the above explanation and edited the script.css and style.css to display the menu block on the RHS, the drop down very nicely appears and disappears when I hover over the primary link. However when I try to do the same for the primary links outside the block, they dont appear. The reason is that the data i.e. the secondary menu items are not in the rendered html. How can I get that data out. I am new to drupal and php.

Thanks in advance.

Vaishali

A Gotcha

It seems if you set the "Source for Primary Links" to Primary Links (Menus >> Settings) in order to use the "non-block" menu Drupal ignores expanded setting. This may be why so many have had problems when trying to go this route rather than using blocks as per the tutorial.

cheers
Paul

Any way around this?

Hi Paul,

I seem to be having this difficulty adapting the tutorial to apply to the non-block based menu I get using zen. Have you found any way to get around this?

Cheers,
Dom

thanks

Eric:
Thanks so much for this detailed explanation and this great article.

Michael

A module

Nice and simple! You can also give Nice menus module a go too. ;-) I know it doesn't suit everyone and is heavier than your tut, but it covers most bases pretty well. In version 2 for Drupal 6 there will also be configurable JS using Superfish (the jQuery fancy enhancements to Suckerfish).

Eric.London's picture

thanks

I am aware of that module, it's a good one. I should have added that this tutorial was created to show coders how to implement css drop down menus on their own, to give them a better understanding of the code under the hood.

Nice to see how things work

Its always good to see how things work without having to rely on modules. I think modules limit the creative freedom of most poeple.

Jimmel

How can this work for Drupal 5.x

HI Eric,

Thanks for taking the time to do this. Since I am not a coder, I am trying to get this to work but do not know which files to alter.

I would like to ask a few questions to "summarize" your tutorial for newbies like myself-

1) Which pages do we download from drupal source files to alter
I guess it would be the page.tpl.php and the main style.css both in the theme directory (is that correct?)

2) Where is the java script you reference to go in the head region of the page.tpl.php? and where does it go?

3) Are there any other CSS pages that need editing to make this work?

I am using Drupal 5.x and amd using the "Drupify" Theme but am not sure where to apply the code you list here.

4) Since I want to be able to use your code to alter or customize the main menu links CSS and cause the main menu items to have this hover effect, how can I do this without having to make the main menu links be configured to a new "block" that I have to configure? It seems that all of the other "menu" modules force you to create new blocks instead of being able to style and configure the default main menu items (and this is the control I am seeking).

Thanks so much for giving to others to help us get better at using Drupal.

Blessings,
Aaron