Search

How to Create a Mega Menu in a WordPress Theme

    Vishal Chitnis
Listen to this article
WisdmLabs-Mega-Menu
Mega Menu on Our Site

Any site or blog has navigation menus. They are a given. Some sites have interestingly styled ones. A week ago we had a requirement to customize a theme for a client. Despite our many out-of-the ordinary, innovative, suggestions for navigation menus (which we considered good), the client wanted a more “serious look and feel” (his words not ours). Not a problem. We’re up for any challenge. But instead of the usual menus, we suggested (because of his restrictive requirement) it would be apt to have a Mega Menu.

[space]

What is a Mega Menu?

Now a Mega Menu, is not a simple drop-down menu. It contains a kind of enlarged sub-menu. You must have certainly come across one. This kind of menu caters to a professional look. It is a great way to provide navigation information to categorised content, and to present data that may be located deep in your site. A Mega Menu can have images and icons, which provide for a user-friendly experience.

[space]

How did we provide a Mega Menu?

In case you wanted to have a Mega Menu as part of your navigation menus, you would need to do the following:

  1. Provide an additional custom field for the Menu post type
    • This field will be later used to add contents to the Mega Menu
  2. Show the custom field each time a menu is being created
    • Create a class which extends Walker_Nav_Menu to display our custom field
    • This will be our custom walker field object
    • Update wp_nav_menu to include the walker field object
  3. Add CSS style classes to style your Mega Menu

(Incase you are lost, do not worry. We will guide you through this.)

[space]

Create a Custom Meta Field for Menu

We used this field to input simple HTML data, which will be used to style and organize the contents, for the Mega Menu.

To create a meta field for the menu post type, we made use of the Sweet Custom Menu Plugin. Download and install this plugin. Basically what this plugin does, is provides an option to add attributes to your menu. A custom field subtitle (the name for the field is provided by the plugin) is created, but not yet displayed with the menu.

Reference: Learn more about the Sweet Custom Menu plugin. Read about how the plugin was created.

[space]

Displaying the custom meta field in a Menu

To include the meta field in the menu, we need to display it through the wp_nav_menu(). This loop displays the menu attributes.

  1. Firstly we had to extend the Walker_Nav_Menu, and create a custom walker object, which will add our custom field(subtitle)  to be displayed. Our custom class, named My_Walker, will have to be placed in the functions.php file of your theme. We have modified the start_el function, to include our field.

class My_Walker extends Walker_Nav_Menu
{
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $item->subtitle;
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

To read more about Walker_Nav_Menu, and the functions, refer this link.

  1. Next we had to include the custom walker object in the Nav Menu Loop. To ensure that the custom walker object is picked up, replace the wp_nav_menu( array(…, with the following, in the header.php.

$walk = new My_Walker();
wp_nav_menu( array( 'theme_location' => 'primary','menu_class' => 'nav navbar-nav navbar-right', 'items_wrap' => '<ul>%3$s</ul>', 'walker' => $walk ) );

OR (you can add a filter in the child theme)

function my_wp_nav_menu_args( $args = '' ) {
  $args['walker'] = new My_Walker();
  return $args;
}
add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );

Now, when you create a new menu, the custom field will be added to every menu item you add.

Mega-Menu-Meta-Field
Meta Field for the Mega Menu

Styling the Mega Menu

We used a set of CSS classes to style our Mega Menu. You could add additional styles as per your requirement. In case you would want to use the same ones, copy this code to the style.css file of your theme.

/* Mega Menu */
.dropdown_1column,
.dropdown_2columns,
.dropdown_3columns,
.dropdown_4columns,
.dropdown_5columns,
.dropdown_fullwidth {
  margin:-3px auto;
  position:absolute;
  left:-999em; /* Hides the drop down */
  text-align:left;
  padding:10px 5px 10px 5px;
  border:1px solid #777777;
  border-top: 2px solid #960000;

  /* Gradient background */
  background:#FFF;

  /* Rounded Corners */
  -moz-border-radius: 0px 0px 5px 5px;
  -webkit-border-radius: 0px 0px 5px 5px;
  border-radius: 0px 0px 5px 5px;
}

.dropdown_1column {width: 140px;}
.dropdown_2columns {width: 280px;}
.dropdown_3columns {width: 420px;}
.dropdown_4columns {width: 560px;}
.dropdown_5columns {width: 700px;}
.dropdown_fullwidth{width: 80%;}

ul.navbar-nav > li:hover > .dropdown_1column,
ul.navbar-nav > li:hover >.dropdown_2columns,
ul.navbar-nav > li:hover > .dropdown_3columns,
ul.navbar-nav > li:hover >.dropdown_4columns,
ul.navbar-nav > li:hover >.dropdown_5columns {
  left:-1px;top:auto;
}

ul.navbar-nav > li:hover >.dropdown_fullwidth{
  position: fixed;
  left:10%;top:auto;
  z-index: 99;
}

Reference: How to Build a CSS3 Mega Drop-Down Menu.

[space]

Finally, how to use this custom field to create a Mega Menu

Eventually, this is how the interface appeared to the client, and he would need to do the following to create a Mega Menu:

  • To add a Mega Menu, he would need to add a Link to the Menu Structure. He would set the desired name but set URL to #

  • He can choose out of all the style classes we have provided to style the Mega Menu div. And add the contents to be displayed in the Menu would be shown using simple HTML tags

Creating-Mega-Menu
Creating the Mega Menu

[space]

Needless to say the client was happy. A Mega Menu is a great way to provide a preview to the contents of any site. And with the approach we took, it worked well with the client’s current theme, and he could customize it in any way he wanted.

But this is an approach we took, because it fit our requirement. Certainly there are some themes out there, which already provide options for a Mega Menu or other plugins you could use. Incase you had a better solution or had any further questions, do share your knowledge or queries with other readers in the comment section below.

Vishal Chitnis

Vishal Chitnis

14 Responses

  1. I’m adding exact codes but its not working as it supposed to be. Can i add everything that i want inside that subtitle seciton. I see the menu but the content that i add is not working like dropdown menu. Any ideas why is that?

  2. Hi Adnan,
    Try adding the content in subtitle field in <div class=”dropdown_5columns”> ….</div> html tags. Also make sure you copy the given CSS to your theme’s style.css .

  3. i get 500 error when i paste this code in “as it is” because you have a number of lines where you have typed a double quotation mark instead of two single quotation marks.

    ex:

    $class_names = $value = ”; (ends in one double quote)

    should read

    $class_names = $value = ”; (now ends in two single quotes)

    I also had to escape the double quotes (the ones that are supposed to be there).

    Here is the updated code (this worked for me):

    class My_Walker extends Walker_Nav_Menu {

    function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( “\t”, $depth ) : ”;

    $class_names = $value = ”;

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;

    $class_names = join( ‘ ‘, apply_filters( ‘nav_menu_css_class’, array_filter( $classes ), $item ) );
    $class_names = ”;

    $output .= $indent . ‘ID . ‘\”‘ . $value . $class_names .’>’;

    $attributes = ! empty( $item->attr_title ) ? ‘ title=\”‘ . esc_attr( $item->attr_title ) .’\”‘ : ”;
    $attributes .= ! empty( $item->target ) ? ‘ target=\”‘ . esc_attr( $item->target ) .’\”‘ : ”;
    $attributes .= ! empty( $item->xfn ) ? ‘ rel=\”‘ . esc_attr( $item->xfn ) .’\”‘ : ”;
    $attributes .= ! empty( $item->url ) ? ‘ href=\”‘ . esc_attr( $item->url ) .’\”‘ : ”;

    $item_output = $args->before;
    $item_output .= ‘‘;
    $item_output .= $args->link_before . apply_filters( ‘the_title’, $item->title, $item->ID ) . $args->link_after;
    $item_output .= ‘
    ‘;
    $item_output .= $item->subtitle;
    $item_output .= $args->after;

    $output .= apply_filters( ‘walker_nav_menu_start_el’, $item_output, $item, $depth, $args );
    }
    }

    function my_wp_nav_menu_args( $args = ” ) {
    $args[‘walker’] = new My_Walker();
    return $args;
    }
    add_filter( ‘wp_nav_menu_args’, ‘my_wp_nav_menu_args’ );

    1. Hi Justin,
      Thank-you for pointing out the issue. The problem was really an error while pasting the code in the WordPress editor. I have made the changes and updated the code.

  4. hi,
    do i have to install “Sweet Custom Menu Plugin” ?
    when adding the field do I have to keep “Sweet Custom Menu Plugin” installed ?

  5. Please can you add an example in a download file ?
    Can we control, How many columns will be in menu ?

    Regards

    1. Hi Mohamed,
      If you use the exact code, you’ll be able to create the mega menu. To control the number of columns, you have to use the appropriate class. For example, dropdown_2columns will be two columns, dropdown_3columns will be 3 columns and so on.

  6. thanks for this tutorial..but im trying to make the wordpress theme where i need to make megamenu to add the images in the sub menus. so i need a field in the menu items to add the images but without using the plugin…
    If you can please help me or guide me by providing the useful references in my email address

Leave a Reply

Your email address will not be published. Required fields are marked *

Get The Latest Updates

Subscribe to our Newsletter

A key to unlock the world of open-source. We promise not to spam your inbox.

Suggested Reads

Join our 55,000+ Subscribers

    The Wisdm Digest delivers all the latest news, and resources from the world of open-source businesses to your inbox.

    Suggested Reads