Create Better Divi Headers

Expand and Collapse Divi Vertical Menu Submenus on Click

by | Aug 17, 2018 | 45 comments

In this tutorial we are going to make the Divi Vertical Menu submenus expand/collapse when the parent menu items are clicked.

We can create such a vertical menu in two different ways: (1) using the Divi MadMenu extension, and (2) using custom code with Divi theme Vertical Navigation, and in this tutorial I’m providing both solutions.

Solution #1: Using the Divi MadMenu Vertical Menu Module

This solution allows you to create the vertical navigation using the Divi MadMenu Vertical Menu module.

This is a much more flexible solution (compared to the Solution #2 below) allowing you to create the vertical navigation using the power of the Divi Builder.

So, if you don’t want to deal with any code then this solution is a great option for you, you can learn more here.

Otherwise, you can try the Solution #2 below, works with the Divi theme native Vertical Navigation.

Solution #2: Using Custom Code with Divi Theme Vertical Navigation

By default the submenus of the Divi theme Vertical Navigation show up when you hover over the parent menu item, and if there are multiple submenu levels then the lower level submenu appears to the left or to the right of the parent submenu (depending on the position of vertical menu: left or right).

We will change this behavior so that the submenus expand/collapse when clicking the parent menu item while being nested inside one another rather than on the left or right hand side.

To implement this collapsing submenus effect for the Divi theme Vertical Navigation we need to use custom JS and CSS.

We’ll use CSS to change the positioning and styling of submenus, and the JS part will make the submenus expand/collapse when clicking the parent menu item.

The JS code used in this tutorial is basically a modified version of the code provided by ET for collapsing the mobile menu submenus (you can read about it here, and you can check out our own version as well).

First let’s change the positioning and styling of the submenus. The important point here is that the submenu positioning needs to be changed from absolute to relative and the left offset set to 0(zero) to place the submenus underneath the parent menu items.

The submenus are animated using CSS by default but we need to disable the animation since we will use jQuery slideToggle() function to animate submenus when expanding/collapsing.

The initial state of submenus needs to be closed, so, we’ll hide them. Also the width of submenu needs to be changed to auto in order to fit into the header container.

/* adjust positioning and styling of submenu */
.et_vertical_nav #main-header #top-menu li ul {
  position: relative;
  display: none;
  top: 0;
  left: 0;
  width: auto;
  border-left-width: 0;
  opacity: 1;
  -webkit-animation: none;
          animation: none;
  visibility: visible;
  -webkit-box-shadow: none;
          box-shadow: none;
  background-color: rgba(0, 0, 0, 0.1);
  margin-bottom: 15px;
  -webkit-transition: none;
  -o-transition: none;
  transition: none;
}

Next let’s decrease header container left and right margin to provide more room to submenus.

/* decrease the menu container left and right margin */
.et_vertical_nav #main-header .container {
  margin: 0 20px;
}

If you have the Fixed header enabled and submenus with many menu items then expanding them all at once may make some of the menu items not accessible due to the fact that the menu does not fit into the screen.

To prevent this we need to make the fixed header container scrollable vertically when the menu items do not fit in.

/* make the fixed header scrollable */
.et_vertical_nav.et_vertical_fixed #page-container #main-header {
  overflow-y: auto;
}
Then decrease submenu top and bottom padding.
/* decrease submenu top and bottom padding */
.nav li ul {
  padding: 5px 0;
}
Adjust lower level submenu positioning and remove the box-shadow.
/* adjust the lower level submenu positioning and remove box-shadow */
.et_vertical_nav #main-header #top-menu li ul ul {
   	top: 0;
  left: 0;
  -webkit-box-shadow: none;
          box-shadow: none;
}
Adjust main menu item links spacing.
/* adjust the menu item links spacing */
.et_vertical_nav #main-header #top-menu > li > a {
  margin-right: 0px;
  padding-right: 0px;
}
Remove main menu parent item down arrow right offset.
/* adjust parent item down arrow position */
.et_vertical_nav #main-header #top-menu > li > a:after {
  right: 0px;
}
Decrease the lower level submenu parent item down arrow right offset.
/* adjust lower level parent item down arrow position */
.et_vertical_nav #top-menu li .menu-item-has-children>a:first-child:after {
  right: 10px;
}
Adjust the submenu item left and right padding.
/* decrease the submenu item left and right padding */
#top-menu li li {
  padding: 0 10px;
}
Change submenu item link width and padding.
/* adjust submenu item link width and padding */
#top-menu li li a {
   	width: auto;
   	padding: 6px;
}
Finally, remove the right border and right offset of the right vertical menu submenu.
/* remove right border and adjust positioning of the right vertical menu submenu */
.et_vertical_nav.et_vertical_right #main-header #top-menu li ul {
  right: 0;
  border-right-width: 0;
}

Bringing all of the CSS together

Now let’s bring all of the CSS snippets above together and wrap them in a media query with min-width of 981px to make sure this CSS applies to desktop menu only.
@media all and (min-width: 981px) {

  /* define positioning and styling for submenu */
  .et_vertical_nav #main-header #top-menu li ul {
    position: relative;
    display: none;
    top: 0;
    left: 0;
    width: auto;
    border-left-width: 0;
    opacity: 1;
    -webkit-animation: none;
        animation: none;
    visibility: visible;
    -webkit-box-shadow: none;
        box-shadow: none;
    background-color: rgba(0, 0, 0, 0.1);
    margin-bottom: 15px;
    -webkit-transition: none;
    -o-transition: none;
    transition: none;
  }
  
  /* decrease the menu container left and right padding */
  .et_vertical_nav #main-header .container {
    margin: 0 20px;
  }

  /* make the fixed header scrollable */
  .et_vertical_nav.et_vertical_fixed #page-container #main-header {
    overflow-y: auto;
  }

  /* decrease the submenu top and bottom padding */
  .nav li ul {
    padding: 5px 0;
  }
  
  /* adjust the lower level submenu positioning and remove box-shadow */
  .et_vertical_nav #main-header #top-menu li ul ul {
    top: 0;
    left: 0;
    -webkit-box-shadow: none;
            box-shadow: none;
  }
  
  /* adjust the menu item links spacing */
  .et_vertical_nav #main-header #top-menu > li > a {
    margin-right: 0px;
    padding-right: 0px;
  }
  
  /* adjust parent item down arrow position */
  .et_vertical_nav #main-header #top-menu > li > a:after {
    right: 0px;
  }
  
  /* adjust lower level parent item down arrow position */
  .et_vertical_nav #top-menu li .menu-item-has-children>a:first-child:after {
    right: 10px;
  }
  
  /* decrease the submenu item left and right padding */
  #top-menu li li {
    padding: 0 10px;
  }
  
  /* adjust submenu item link width and padding */
  #top-menu li li a {
     	width: auto;
     	padding: 6px;
  }
  
  /* remove right border and adjust positioning of the right vertical menu submenu */
  .et_vertical_nav.et_vertical_right #main-header #top-menu li ul {
    right: 0;
    border-right-width: 0;
  }
  
}
Add this CSS either into the Custom CSS field on Divi -> Theme Options page or to you child theme style.css file and save.

Adding JS

After applying the CSS provided above we have moved submenus underneath their parent menu items but they are not visible since we’ve hid them because they need to be closed on initial page load.

Next we have to make the submenus expand and collapse when we click the parent menu items. To do that we’ll use the following code snippet:

<script type="text/javascript">
  
  (function($){
    function collapse_vertical_menu_submenus() {
      
      var $menu = $('#top-menu'),
        top_level_link = '#top-menu .menu-item-has-children > a';

      $menu.find('a').each(function() {
        $(this).off('click');

        if ( $(this).is(top_level_link) ) {
          $(this).attr('href', '#');
        }

        if ( $(this).siblings('.sub-menu').length ) {
          $(this).on('click', function(event) {
            event.preventDefault();
            $(this).siblings('.sub-menu').slideToggle();
          });
        }
      });
    }

    $(window).load(function() {
      collapse_vertical_menu_submenus();
    });

  })(jQuery);
  
</script>
Add this JS into the Add code to the < head > of your blog field in Divi -> Theme Options page Integration tab, save and you’re done!

If you want to show and hide the Divi Vertical Navigation on click then you might want to check out this tutorial: Show and Hide Divi Vertical Navigation on Click , they work very well with each other.

Adjustments for the Divi Desktop Menu Customizer plugin

If you are using the Divi Desktop Menu Customizer plugin, you need to add the following CSS as well (in addition to the CSS provided above):
/* Adjustments for DMC plugin */
@media all and (min-width: 981px) {
  #main-header #top-menu li ul {
    -webkit-transition: none !important;
    -o-transition: none !important;
    transition: none !important;
  }
  .chi_dmc_default.et_vertical_nav:not(.et_vertical_right) #main-header #top-menu > li > ul,
  .chi_dmc_default.et_vertical_nav:not(.et_vertical_right) #main-header.et-fixed-header #top-menu > li > ul,
  .et_header_style_centered.et_vertical_nav:not(.et_vertical_right) #main-header #top-menu > li > ul,
  .et_header_style_centered.et_vertical_nav:not(.et_vertical_right) #main-header.et-fixed-header #top-menu > li > ul {
    left: 0 !important;
  }
  .chi_dmc_default.et_vertical_nav.et_vertical_right #main-header #top-menu > li > ul,
  .chi_dmc_default.et_vertical_nav.et_vertical_right #main-header.et-fixed-header #top-menu > li > ul,
  .et_header_style_centered.et_vertical_nav.et_vertical_right #main-header #top-menu > li > ul,
  .et_header_style_centered.et_vertical_nav.et_vertical_right #main-header.et-fixed-header #top-menu > li > ul {
    right: 0 !important;
  }
  .chi_dmc_default.et_vertical_nav #main-header #top-menu li ul ul,
  .chi_dmc_default.et_vertical_nav #main-header.et-fixed-header #top-menu li ul ul,
  .et_header_style_centered.et_vertical_nav #main-header #top-menu li ul ul,
  .et_header_style_centered.et_vertical_nav #main-header.et-fixed-header #top-menu li ul ul {
    left: 0;
  }
  .chi_dmc_default.et_vertical_nav.et_vertical_right #main-header #top-menu li li ul,
  .chi_dmc_default.et_vertical_nav.et_vertical_right #main-header.et-fixed-header #top-menu li li ul,
  .et_header_style_centered.et_vertical_nav.et_vertical_right #main-header #top-menu li li ul,
  .et_header_style_centered.et_vertical_nav.et_vertical_right #main-header.et-fixed-header #top-menu li li ul {
    right: 0;
  }
  .chi_dmc_default #main-header #top-menu li:not(.mega-menu) li a,
  .chi_dmc_default #main-header.et-fixed-header #top-menu li:not(.mega-menu) li a,
  .et_header_style_centered #top-menu li:not(.mega-menu) li a,
  .et_header_style_centered #main-header.et-fixed-header #top-menu li:not(.mega-menu) li a {
    width: auto;
  }
  .chi_dmc_default.et_vertical_nav #main-header #top-menu li ul ul,
  .chi_dmc_default.et_vertical_nav #main-header.et-fixed-header #top-menu li ul ul,
  .et_header_style_centered.et_vertical_nav #main-header #top-menu li ul ul,
  .et_header_style_centered.et_vertical_nav #main-header.et-fixed-header #top-menu li ul ul {
    top: 0;
  }
}
/* END Adjustments for DMC plugin */
That’s all, hope you’ll find this tutorial useful. Share it with your friends and feel free to leave your thoughts and suggestions in the comments section below and subscribe to stay updated ;)

Subscribe To Our Newsletter

Join our mailing list to download Divi freebies and get notified of our discounts, latest news and updates.

You have Successfully Subscribed! Please confirm your email address.

Divi MadMenu Coming Soon!

Join our mailing list to get notified when the Divi MadMenu module is released! Check out the sneak peek...

You have Successfully Subscribed! Please confirm your email address.

Get FREE Divi Layouts

Download 20+ Divi templates for FREE!

Please confirm your email address to complete your subscription. Thank you!

Black Friday Is Coming!

Subscribe to get notified when our BIGGEST SALE starts!

Please confirm your email address to complete your subscription. Thank you!

Cyber Monday Is Coming!

Subscribe to get notified when the SALE starts!

Please confirm your email address to complete your subscription. Thank you!

Black Friday Is Coming!

Subscribe to get notified when our BIGGEST SALE starts!

Please confirm your email address to complete your subscription. Thank you!