Creating a Mega Menu with mojoPortal

Posted by Steve Railsback Monday, August 08, 2011 4:05:00 PM Categories: CSS MojoPortal Skins

Mega Menus are fast becoming the new design trend. They are a new spin on the traditional drop-down menu. These big two-dimensional menus group information by category and eliminate the need to drill though the traditional drop-down menu levels to find a particular page. Use of mega menus reduces site complexity and improves usability.

I wanted to implement a mega menu on one of my sites, but all the examples that I found required specialized markup or rely upon javascript to render the menu. My goal was to create a mega menu using only the tools provided by mojoPortal; namely the <portal:SiteMenu /> control. In addition I did not want to rely upon javascript to create the menu. After studying the control I realized that by changing the site menu's structure and some simple CSS I could achieve the desired effect. Here's how I did it. For this example I am using the styleshout-citrisland skin, it's been modified for my site, but the basic structure is still there. Here's an example of the final product.

Site Menu

Let's begin with creating our mega menu. The basic structure of our mega menu is two-levels deep with three to four columns across and categorical headings for each column. Our first task is to create 'hook' that will trigger the mega menu. For each of the parent pages belonging to the root, add the megaMenu Custom Mega Menu Class (Page Settings → Custom Menu CSS Class). Next we need to create new pages that will serve as category headings in our mega menu. Use a meaningful name for these pages and assign the megaMenuHeading class under Custom Menu CSS Class. Finally, group the child pages into each of the newly created category. You may use existing pages in your menu if you prefer as well. I just found it easier just to create new pages. For parent menu items where you do not need the mega menu, just add the noMegaMenu Custom Menu CSS Class.


Root
Parent (megaMenu class)
Category (megaMenuHeading class)
Child
Child
Child
Category (megaMenuHeading class)
Child
Child
Child
Parent (noMegaMenu class)
Child
Child
Child

If you are familiar mojoPortal's database you an can change the parent id's in the table manually. This may save you some time.

Site Menu Control

After reorganizing the site menu I changed the SiteMenu control in the layout.master. My mega menu will be horizontal and have two dimensions.

        <div id="siteNav">
<portal:SiteMenu id="SiteMenu1"
runat="server"
UseTreeView="false"
UseSpanInLinks="true"
HideMenuOnSiteMap="false"
Direction="Horizontal"
TopLevelOnly="false"
dynamicDisplayLevels="2"></portal:SiteMenu>
</div>

Note, I usually wrap my SiteMenu control with a siteNav selector. Though not necessary, this selector positions and defines the base properties of the site menu and makes it easier to access menu elements without typing out the complex AspNet-Tree view selectors.

Stylesheet

Now it's time for the magic. Backup your stylemenu.css file just so you have a fall-back. Delete all the css rules in stylemenu.css and paste the rules below into the file.


#siteNav {
width: 660px;
margin: 23px 0 0 0;
float: right;
font-size: 1.5em;
}

div.AspNet-Menu-Horizontal { position: relative; }

div.AspNet-Menu-Horizontal ul.AspNet-Menu {
position: relative; /* position the ul relative to it's parent */
margin: 0;
padding: 0;
width: 100%;
list-style-type: none;
}

div.AspNet-Menu-Horizontal ul.AspNet-Menu li {
float: left;
}

div.AspNet-Menu-Horizontal ul.AspNet-Menu li img {
display:none;
}

div.AspNet-Menu-Horizontal ul.AspNet-Menu li a {
color: #fff;
text-decoration: none;
padding: 9px 10px;
text-align: center;
display: block;
font-size: 1.1em;
}

div.AspNet-Menu-Horizontal ul.AspNet-Menu li a:hover{
color: #B38807;
}

div.AspNet-Menu-Horizontal ul.AspNet-Menu li.AspNet-Menu-SelectedWithChildren a.AspNet-Menu ,
div.AspNet-Menu-Horizontal ul.AspNet-Menu li.AspNet-Menu-SelectedLeaf a.AspNet-Menu { }


/* mega menu */
div.AspNet-Menu-Horizontal ul.AspNet-Menu ul { display:none; }
div.AspNet-Menu-Horizontal ul.AspNet-Menu li:hover ul { display:block; }


/* menu styles */
li a.megaMenu + ul,
li a.noMegaMenu + ul
{
background-color: #fff;
border: 1px solid #ccc;
padding: 20px;
display: block;
position: absolute;
left: 0;
z-index: 1;
font-size: .9em;

/* ccs3 styles border radius - will throw validator error, just ignore */
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;

/* ccs3 styles drop shadow */
-moz-box-shadow: 0px 4px 4px #5a5a5a;
-webkit-box-shadow: 0px 4px 4px #5a5a5a;
box-shadow: 0px 4px 4px #5a5a5a;
}

li a.megaMenu + ul { width: 660px; } /* mega menu width */
li a.noMegaMenu + ul { width: 200px; } /* single column width */




/* mega menu children */
li a.megaMenu + ul li a.megaMenuHeading {
width: 200px !important;
margin: 0 20px 0 0 !important;
}

li a.megaMenu + ul li a.megaMenuHeading + ul {
width: 200px;
margin: 0 !important;
padding: 0;

}

li a.megaMenu + ul li a.megaMenuHeading + ul li a {
width: 200px;
}

li a.megaMenu + ul li a {
text-align: left !important;
padding: 10px 0 0 0 !important;
}

li a.megaMenu + ul li.AspNet-Menu-Leaf {
margin: 0;
padding: 0;
width: 220px;
}

li a.megaMenu + ul li.AspNet-Menu-Leaf a {
font-size: .9em;
color: #333;
width: 100%;
text-decoration: underline;
}

/* mega menu sub category headings */
li a.megaMenu + ul li a.megaMenuHeading
{
color: #B38807;
font-size: normal;
display: block;
height: auto;
margin: 0;
padding: 0;
width: 100%;
border-bottom: 1px dotted #ccc;
}

li a.megaMenu + ul li a.megaMenuHeading + ul li {
list-style-type: square !important;
margin: 0 0 0 0;
padding: 0;
width: 180px;
}

li a.megaMenu + ul li a.megaMenuHeading + ul li a {
border: none;
}

li a.megaMenu + ul li.AspNet-Menu-WithChildren,
li a.megaMenu + ul li.AspNet-Menu-Leaf {
float: left;
display: block;
}

li a.megaMenu + ul li.AspNet-Menu-WithChildren ul ,
li a.megaMenu + ul li.AspNet-Menu-Leaf ul {
list-style-type: square;
}



/* noMegaMenu
Will render single-column drop down, one level deep */
li a.noMegaMenu + ul li {
margin: 0 0 0 0 !important;
list-style: none;
}


li a.noMegaMenu + ul li a {
font-size: .8em !important;
color: #333 !important;
text-decoration: underline !important;
margin: 0 0 0 0 !important;
padding: 7px !important;
}

li a.noMegaMenu + ul li a:hover { color: #B38807 !important; }
li a.noMegaMenu + ul li { clear: both !important; }

Here's what's going on. The trick to creating the mega menu is positioning and the use of sibling selectors. First we position the div.AspNet-Horizontal and div.AspNet-Menu-Horizontal ul.Asp-Net-Menu selectors relative to their parents.


div.AspNet-Menu-Horizontal { position: relative; }

div.AspNet-Menu-Horizontal ul.AspNet-Menu {
position: relative;
margin: 0;
padding: 0;
width: 100%;
list-style-type: none;
}

Then we absolutely position the sibling unordered lists, li a.megaMenu + ul and li a.noMegaMenu + ul, selectors to the left.


li a.megaMenu + ul, li a.noMegaMenu + ul
{
background-color: #fff;
border: 1px solid #ccc;
padding: 20px;
display: block;
position: absolute;
left: 0;
z-index: 1;
font-size: .9em;
/* ccs3 styles border radius - will throw validator error, just ignore */
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;

/* ccs3 styles drop shadow */
-moz-box-shadow: 0px 4px 4px #5a5a5a;
-webkit-box-shadow: 0px 4px 4px #5a5a5a;
box-shadow: 0px 4px 4px #5a5a5a;
}

The megaMenu and noMegaMenu classes define the width of the drop-down.


li a.megaMenu + ul { width: 660px; } /* mega menu width */
li a.noMegaMenu + ul { width: 200px; } /* single column width */

To create the multi-column effect inside the mega menu all we need to do is define the width of the sibling unordered list li a.megaMenu + ul li.AspNet-Menu-WithChildren ul, li a.megaMenu + ul li.AspNet-Menu-Leaf + ul, and float them left.


li a.megaMenu + ul li.AspNet-Menu-WithChildren, li a.megaMenu + ul li.AspNet-Menu-Leaf {
float: left;
display: block;
}

Lastly, we add some style to the category headings.


li a.megaMenu + ul li a.megaMenuHeading
{
color: #B38807;
font-size: normal;
display: block;
height: auto;
margin: 0;
padding: 0;
width: 100%;
border-bottom: 1px dotted #ccc;
}

As with all things Internet Explorer we need to add an additional rule to accommodate for IE7. Open the IE7Specific.css file and add the following rule, which just corrects for the mega menu positioning.


li a.megaMenuParent + ul { left: -40px; }

That's it. With some additional CSS work we could even add background images to the category headings or add drop-down effects using jQuery. I've tested this with FireFox, Safari, Chrome, and IE with great success. One last note, you might have caught the use of CSS3 rules in the above code. Most css-validators will issue a warning because CSS3 is standardized. You can breeze over these errors since most modern-day browsers due support CSS3 (IE7 and lower excluded). The use of CSS3 is purely for presentation – rounded corners and drop shadows. Our mega menu will render fine without the aid CSS3. Those on IE7 or non standard browsers would just see a square box without the drop shadow.

Update: Dropdown menus using the noMegaMenu will have a left positioning of 0px. To overcome this just add an additional page menu to compensates for the incorrect positioning. Ex: .noMegaMenu1 { left: 50px; }

 

 

Comments are closed on this post.