Drupal Theme Design Tutorial 2 - Mega MenusDrupal Theme Design Tutorial 2 - Mega Menus

Categories:

This is the second installment in our ongoing series on unique drupal themeing techniques. As before, my goal is to inform you of the elements you need to design for and demonstrate how to make Drupal not look like Drupal. I just want to throw out a quick thanks for all the positive reactions we had to the first installment. It really helps to know that people are finding our tutorials useful.

We're going to take a quick look at what we are going to be accomplishing today. Good navigation is one of the hardest things to balance on a new site. There are many problems that come into play when we start talking about e-commerce and large corporate website with many tiers of navigation. What is the best way to convey all that information to the user? Do we go with nested drop down menus, large numbers of top-tier links, or primary, secondary (or even tertiary) navigation areas?

One of the best things that has come out of the last year or 2 has been widespread use of what are called "mega menus." Mega menus are basically large navigation blocks that show up upon rollover of a primary navigation item. The goal is to show lots of options or tiers within this area. So instead of displaying everything up front or within a series of nested drop down menus, you get everything in one nice package. Here is a screen shot of what we will be building today:

Regular primary navigation:

Before

 

After rollover:

After

Just look at how many useful links and features we can squeeze into this area. This helps declutter the actual page content while still maintaining a robust navigation structure throughout the site. As you can see we'll be listing several product categories as well as having special areas near the bottom for product filtering. I will be using a slightly modified version of the Garland theme (right, center aligned navigation instead of the default). We will be using the Mega Menus module for Drupal 6 which is great because it saves us from having to any TPL or PHP work. Our strategy will be to first install modules and set up links using Drupal's built-in menu system. Lastly we will be styling with CSS.


1. Module installation & setup:

Head to drupal.org and grab the most recent version of the Mega Menus module. At the time of writing, I used 6.x-2.0-beta2. Install and enable it.

The Primary navigation menu should already be active and enabled by default when you installed Drupal, but if it hasn't, make a new primary menu. Next, head to /admin/build/megamenu and check to enable the primary navigation as a mega menu. Save and then click "configure mega." You might want to play with some of the settings at a later time, but for purposes of this tutorial we are going to select "horizontal" and "columnar" orientation. Since we are styling our own menus, select "Use your own custom skin" and type a name into the next box. This is how we will target the menu with our own CSS. I chose "mytheme" and the CSS in this tutorial will use that title.

 

2. Setting up your menu items:

You should be no doubt familiar with Drupal's menu system. The Mega menus module will create menus that follow the following schema: Top tier items will always be visible on the page; 2nd tier items are the categories for the drop down (they will still exist as links, however); 3rd tier items are the links within a given category.
 
Let's take a look at an example of how I set up my menu and how it translates to the menu:
 
Menu system
 
As far as the brand icons at the bottom, just note that those are all 2nd tier items with no 3rd tier. Same goes for colors. We will be making special styles for these items. The great thing about this is that we can go back and add/delete items as needed without having to peel open TPL files. Go ahead and take a few minutes to populate your navigation before we move on to styling.
 
 

3. CSS Time:

Ok now the work really starts. We have to take our output and style it to our liking. Styling a module that you are unfamiliar can be a daunting task, but luckily the module creators have done a stellar job with div ids and classes that will make the process relatively easy Let's take it one section at a time. Let's start by looking at how the module structures the HTML code:

HTML structure

The mega menus module adds some key markup to the output. Notice the 3 "ul" classes: "megamenu-skin-mytheme," "megamenu-bin," and "megamenu-items" which represent the 3 tiers of navigation. Actual navigation link text is wrapped with h2 or h3 tags. Lastly, all individual navigation links have their own li ids for easy single targeting. Also note one class that you cannot see here, while mousing over a top tier primary navigation item, the entire li (and thus all the lists underneath it) gets an additional class called "hovering."

So where do we start? Well, mileage on your own themes will vary, but since I am using Garland I have to undo some link styling that prevents my links from being underlined upon mouse hovering:

 

.megamenu-skin-mytheme a:hover, .megamenu-skin-mytheme li.hovering a {
text-decoration:none;
}

 

Next we need to style the top tier of links. I'll be giving the links plenty of padding as well as adding the drop down arrows. Note that for each item in this tier the arrow will need to be positioned slightly differently (depending on the width of the word):

 

.megamenu-skin-mytheme .megamenu-parent-title a {
color:#ffffff;
padding:10px 25px 10px 10px;
margin:0 20px 0 0;
font-size:1.4em;
line-height:1em;
background-image:url(arrow-inactive.png);
background-repeat:no-repeat;
} a.menu-219 {
background-position:82px center;
}
a.menu-220 {
background-position:80px center;
}
a.menu-221 {
background-position:82px center;
}
a.menu-222 {
background-position:104px center;
}

 

We also need a rollover state for this item. I exported a second arrow which is grey and will change the rollover background to white so that we can get a nice big unified box. Lastly, a little CSS rounded corner action on the primary links might be a nice touch. Note the use of "li.hovering" here to apply styling only when the mouse is hovering over the navigation link:

 

.megamenu-skin-mytheme li.hovering .megamenu-parent-title a {
color:#777777;
background-color:#ffffff;
background-image:url(arrow-active.png);
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
}

 

Here is the output for normal and rollover states:

 

Top tier rollover states

 

Now let's talk about the megamenu container. We will be targeting ".megamenu-bin." The styling will need some padding as well as appropriate font sizes. I am cranking the font size down a few notches to ensure we can fit everything within a reasonable space and increasing the line-height to increase readability. A top margin will be added to push the menu box a bit further down than it would normally be. I am giving my menu box a static width in this case because I want to do some special styling with the brand and color selectors. The Mega menus module calculates and applies box widths by itself according to the number of lists within a given window. This causes issues when I will be pushing the brand and color lists below the others (which would leave a big empty space to the right where the lists once lived), so I need to readjust the window width manually using the "!important" flag. If you use this technique you might want to use more specific CSS targeting on each menu window. Lastly, I am adding a CSS drop shadow because I want it to be very clear that the window is separate from the underlying page content. Typical CSS layering will force the drop shadow to actually spill out over the primary navigation links so we need to tuck it back with a z-index value.

 

.megamenu-skin-mytheme .megamenu-bin {
z-index:-1;
padding:20px;
margin-top:8px;
background-color:#ffffff;
font-size:0.9em;
line-height:2em;
width:1084px !important;
-moz-box-shadow: 0px 0px 10px #555555;
-webkit-box-shadow: 0px 0px 10px #555555;
box-shadow: 0px 0px 10px #555555;
}

 

Styling the actual lists is easy. We will target ".megamenu-slot" to give a slight dotted border and margins. Remember as with any list we need to "deborder" and "demargin" the last items in a row.

 

.megamenu-skin-mytheme .megamenu-slot {
margin:0 20px 40px 0;
border-right:1px dotted #bbbbbb;
}
.megamenu-skin-mytheme .megamenu-slot-4, .megamenu-skin-mytheme .megamenu-slot.last {
margin-right: 0;
border-right:none
}

 

To finish the default lists we need to style the category headers and list items. I am going to add small arrows to each list item. Remember that category headers will actually still be clickable links.

 

.megamenu-skin-mytheme .megamenu-slot-title a {
color:#888888;
font-weight:bold;
text-transform:uppercase;
}
.megamenu-skin-mytheme .megamenu-items li {
list-style:inside url(arrow.png);
}

 

And the output:

 

List styling output

 

So far so good. Now for the brand and color selectors we're going to need to do some CSS magic. These lists are classed as ".megamenu-slot-5" and ".megamenu-slot-6" so we will target them using those names. First we need to clear the floated lists so that they drop down to the next level. We'll also be setting hard widths on these lists so that they line up nicely with the lists above them. Our list items need to line up in a row and lack the list arrow as well.

 

.megamenu-skin-mytheme .megamenu-slot-5 {
width:642px;
clear:both;
margin-bottom:10px;
}
.megamenu-skin-mytheme .megamenu-slot-6 {
width:410px;
margin-bottom:10px;
} .megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li,
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li {
list-style:none;
display:inline;
}

 

Next we will use a technique called CSS sprites to replace text with images. If you are unfamiliar with this technique you can read more about it at A List Apart. Basically what we do is export all the logos and color circles in 2 images which will look like this:

 

Logos

 

Colors

 

This will allow us to replace each link with the appropriate image. Thinking ahead, I have exported my images in a uniform way with regards to spacing and sizing so that all the links share a single height and width. Remember that ".megamenu-slot-5" is the logo list and ".megamenu-slot-6" is the color list. The technique we will use involves setting a width on the link, hiding overflow, and then pushing the text out of the way using top padding that is equal to your desired link height. The actual declared height of 0 prevents the text from appearing while still allowing the background to show through. Links need to be floated to make the styling work properly.

 

.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a {
margin:10px 30px 0 0;
float:left;
width:75px;
height:0px;
padding-top:43px;
overflow:hidden;
background-image:url(logos.png);
background-repeat:none;
} .megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a {
margin:10px 10px 0 0;
float:left;
width:19px;
height:0px;
padding-top:19px;
overflow:hidden;
background-image:url(colors.png);
background-repeat:none;
}

 

The big pain with sprites is that all links need to have their backgrounds manually set using "background-position." Since my image spacing is uniform I just add a constant value continuously get get my appropriate position values:

 

.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a.menu-295 {
background-position:-76px 0;
}
.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a.menu-294 {
background-position:-152px 0;
}
.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a.menu-296 {
background-position:-228px 0;
}
.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a.menu-305 {
background-position:-304px 0;
}
.megamenu-skin-mytheme .megamenu-slot-5 .megamenu-items li a.menu-306 {
background-position:-380px 0;
} .megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-301 {
background-position:-19px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-298 {
background-position:-38px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-303 {
background-position:-57px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-297 {
background-position:-76px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-304 {
background-position:-95px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-302 {
background-position:-114px 0;
}
.megamenu-skin-mytheme .megamenu-slot-6 .megamenu-items li a.menu-299 {
background-position:-133px 0;
}

 

And that is it! When you are done you should have something that looks like this:

 

Finished

 

You might be wondering how you might use the brand and color filters to actually return meaningful results within Drupal. The answer is Views arguments. Set up arguments for each and then set your menu link to return a result for that argument (e.g if you link arguments to '/products/[argument]' then you can simply link each from the appropriate menu item. A video on how to use Views arguments can be found here.



4. Browser Issues:

If you are concerned about IE's lack of CSS3 support, like in my other tutorial I recommend a package you can install to allow IE 6-8 to pick up CSS3 declarations. It's called CSS3PIE and you can check it out here.

IE7 also appears to have issues with general styling. Make sure you trigger a conditional stylesheet for IE7 that contains this CSS:

 

.megamenu-skin-mytheme .megamenu-bin {
margin-top:38px;
}
.megamenu-skin-mytheme .megamenu-items li {
list-style-image:none;
list-style-position:outside;
background:url(arrow.png) center left no-repeat;
padding-left:8px;
}
.megamenu-skin-mytheme li.megamenu-slot-6 {
margin-top:85px;
}

 

There you have it! Useful menus can really make you site stand apart and help your users immensely. Luckily with a simple module implementation we can make this all happen easily within Drupal.

Neha's picture

I have tried to design my mega menu navigation bar according to above mentioned css. I have uplaoded a megatheme.css file in the theme folder's having the following path
sites/all/themes/themename/css/megatheme.css

But it is not working. Can you please mention the path where to uplaod the new custom css file.

Anonymous's picture

Do you have a link to the demo site where you did this? I'd really like to see the website in action from this demo...thanks!

Matt's picture

Hello! I did this locally on my workstation but the Mega Menu module page lists several example sites that use the module online as well.

akaww's picture

The thing I don't understand how to do is make a relationship between these drop-down menus and menu blocks on the page. For instance lets say I want to create a drop down menu for the about section. How then do I have just the "about" sub-pages listed in a block on the page. The way I have done this in the past is to just go and create an "about" menu. However, in no time I then have a ton of different menus when everything I really want is already listed in the primary menu.

Matt's picture

It's been a while but I think you should check out: http://drupal.org/project/menu_block

 

FilmKnurd's picture

As a maintainer of the megamenu module, thank you so much for such a thorough tutorial. This will be very helpful for people.

Drupal Theme Garden's picture

thanks for the article, Nice Menus module looks really great.

Do you maybe know how stable is Drupal 7 version of this module?

Matt's picture

Hey there! The module does not yet have a recommended release for Drupal 7. It looks like it has 1 critical issue left that returns an error message for some users.

James Chapman's picture

Great tutorial... wish I'd seen this a couple of months ago.

Just completed two sites using mega menus achieving them with regions and blocks.

I'm never cease to be amazed with the capabilities of Drupal both with modules and customisation.

Thanks again!

Mario Hernandez's picture

Awesome! Excellent tutorial. Definitely will keep it for future reference.

Thank you.

BTMash's picture

This is an excellent tutorial. Thank you for sharing it with us. The roadmap laid out for Mega Menus definitely makes it look like it is in good hands and I'm looking forward to seeing more of Mega Menus and where it heads for Drupal 7.

Need a Custom Designed Theme?

If you need a custom designed theme for your business then our designers can work with you to create a unique concept that is consistent with your brand, clearly communicates your value proposition and helps you achieve your goals. >> Click here to contact us and let us know about your needs and we'll analyze and provide you with an estimate for designing and development your custom theme.