Drop Down Menu with Submenu using WordPress walker class

In this tutorial, I will walk you through how to use the existing HTML/CSS Drop Down Menu with Submenu using WordPress walker class. This tutorial will not show you how to create a menu from scratch but will walk you through the process of taking existing HTML menu themes and applying them to a menu that is built with WordPress. Building a WordPress drop-down menu this way can save you a bundle of time if you are looking for a pre-designed solution.

Follow the simple steps given bellow

Step 1 – Add styles to the stylesheet for WordPress walker

Add the following styles to the active theme’s styles.css

/*CSS for menu*/
@import url(http://fonts.googleapis.com/css?family=Oxygen+Mono);

/* Starter CSS for Menu */
#tutsocean_cssmenu {
 padding: 0;
 margin: 0;
 border: 0;
 width: auto;
}

#tutsocean_cssmenu ul,
#tutsocean_cssmenu li {
 list-style: none;
 margin: 0;
 padding: 0;
}

#tutsocean_cssmenu ul {
 position: relative;
 z-index: 597;
}

#tutsocean_cssmenu ul li {
 float: left;
 min-height: 1px;
 vertical-align: middle;
}

#tutsocean_cssmenu ul li.hover,
#tutsocean_cssmenu ul li:hover {
 position: relative;
 z-index: 599;
 cursor: default;
}

#tutsocean_cssmenu ul ul {
 visibility: hidden;
 position: absolute;
 top: 100%;
 left: 0;
 z-index: 598;
 width: 100%;
}

#tutsocean_cssmenu ul ul li {
 float: none;
}

#tutsocean_cssmenu ul ul ul {
 top: 0;
 left: 190px;
 width: 190px;
}

#tutsocean_cssmenu ul li:hover>ul {
 visibility: visible;
}

#tutsocean_cssmenu ul ul {
 bottom: 0;
 left: 0;
}

#tutsocean_cssmenu ul ul {
 margin-top: 0;
}

#tutsocean_cssmenu ul ul li {
 font-weight: normal;
}

#tutsocean_cssmenu a {
 display: block;
 line-height: 1em;
 text-decoration: none;
}

/* Custom CSS Styles */
#tutsocean_cssmenu {
 background: #333333;
 border-bottom: 4px solid #1b9bff;
 font-family: 'Oxygen Mono', Tahoma, Arial, sans-serif;
 font-size: 12px;
}

#tutsocean_cssmenu>ul {
 *display: inline-block;
}

#tutsocean_cssmenu:after,
#tutsocean_cssmenu ul:after {
 content: '';
 display: block;
 clear: both;
}

#tutsocean_cssmenu ul {
 text-transform: uppercase;
}

#tutsocean_cssmenu ul ul {
 border-top: 4px solid #1b9bff;
 text-transform: none;
 min-width: 190px;
}

#tutsocean_cssmenu ul ul a {
 background: #1b9bff;
 color: #ffffff;
 border: 1px solid #0082e7;
 border-top: 0 none;
 line-height: 150%;
 padding: 16px 20px;
 font-size: 12px;
}

#tutsocean_cssmenu ul ul ul {
 border-top: 0 none;
}

#tutsocean_cssmenu ul ul li {
 position: relative;
}

#tutsocean_cssmenu ul ul li:first-child>a {
 border-top: 1px solid #0082e7;
}

#tutsocean_cssmenu ul ul li:hover>a {
 background: #4eb1ff;
 color: #ffffff;
}

#tutsocean_cssmenu ul ul li:last-child>a {
 -moz-border-radius: 0 0 3px 3px;
 -webkit-border-radius: 0 0 3px 3px;
 border-radius: 0 0 3px 3px;
 -moz-background-clip: padding;
 -webkit-background-clip: padding-box;
 background-clip: padding-box;
 -moz-box-shadow: 0 1px 0 #1b9bff;
 -webkit-box-shadow: 0 1px 0 #1b9bff;
 box-shadow: 0 1px 0 #1b9bff;
}

#tutsocean_cssmenu ul ul li:last-child:hover>a {
 -moz-border-radius: 0 0 0 3px;
 -webkit-border-radius: 0 0 0 3px;
 border-radius: 0 0 0 3px;
 -moz-background-clip: padding;
 -webkit-background-clip: padding-box;
 background-clip: padding-box;
}

#tutsocean_cssmenu ul ul li.has-sub>a:after {
 content: '+';
 position: absolute;
 top: 50%;
 right: 15px;
 margin-top: -8px;
}

#tutsocean_cssmenu ul li:hover>a,
#tutsocean_cssmenu ul li.active>a {
 background: #1b9bff;
 color: #ffffff;
}

#tutsocean_cssmenu ul li.has-sub>a:after {
 content: '+';
 margin-left: 5px;
}

#tutsocean_cssmenu ul li.last ul {
 left: auto;
 right: 0;
}

#tutsocean_cssmenu ul li.last ul ul {
 left: auto;
 right: 99.5%;
}

#tutsocean_cssmenu a {
 background: #333333;
 color: #CBCBCB;
 padding: 0 20px;
}

#tutsocean_cssmenu>ul>li>a {
 line-height: 48px;
 font-size: 12px;
}

/*End of CSS for menu*/

Step 2 – Create a menu in WordPress for WordPress walker

Now as we have added all the styling to the theme, it’s time to create a menu in WordPress with sub-menus. Something like a tree structure.

Go to appearance -> menus and create a menu with any name and add as many items as you want.

Step 3 – Add our Custom Walker Class to functions.php

We have created a custom WordPress Walker Class to make our menus more compatible with WordPress. This class alters the HTML output of your WordPress menu so that it will match the structure of the menus on our site. This will allow us to simply drop in the CSS code to get a menu theme working.

Add the following code to your active theme’s functions.php file

<?php
class tutsocean_CSS_Menu_Walker extends Walker {
    var $db_fields = array('parent' => 'menu_item_parent', 'id' => 'db_id');
    function start_lvl(&$output, $depth = 0, $args = array()) {
        $indent = str_repeat("t", $depth);
        $output.= "n$indent<ul>n";
    }
    function end_lvl(&$output, $depth = 0, $args = array()) {
        $indent = str_repeat("t", $depth);
        $output.= "$indent</ul>n";
    }
    function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
        global $wp_query;
        $indent = ($depth) ? str_repeat("t", $depth) : '';
        $class_names = $value = '';
        $classes = empty($item->classes) ? array() : (array)$item->classes;
        /* Add active class */
        if (in_array('current-menu-item', $classes)) {
            $classes[] = 'active';
            unset($classes['current-menu-item']);
        }
        /* Check for children */
        $children = get_posts(array('post_type' => 'nav_menu_item', 'nopaging' => true, 'numberposts' => 1, 'meta_key' => '_menu_item_menu_item_parent', 'meta_value' => $item->ID));
        if (!empty($children)) {
            $classes[] = 'has-sub';
        }
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';
        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
        $id = $id ? ' id="' . esc_attr($id) . '"' : '';
        $output.= $indent . '<li' . $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 . '><span>';
        $item_output.= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output.= '</span></a>';
        $item_output.= $args->after;
        $output.= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
    function end_el(&$output, $item, $depth = 0, $args = array()) {
        $output.= "</li>n";
    }
}

Step 4: Print Menu in Theme File

Now that we have our custom Walker function in place we need to actually print the menu in one of our template files. Place the below PHP snippet in any template file that you would like your menu to show up on. Mostly we add a menu in the header section of our website but it can vary as per requirement.

wp_nav_menu(array(  
  'menu' => 'Main Navigation', 
  'container_id' => 'tutsoceancssmenu', 
  'walker' => new tutsocean_CSS_Menu_Walker()
));
  • ‘menu’ => Name of the menu you created in Step 3.
  • ‘container_id’ => The id that will be applied to the containing DIV around the menu. ‘tutsoceancssmenu‘ is our default that we use on the site. You can change this if you want but you will also have to change the CSS later.
  • ‘walker’ => This tells the menu to use our custom Walker class to print out the HTML