Expand and Collapse Divi Vertical Menu Submenus on Click

by | Aug 17, 2018 | 2 comments

In this tutorial we are going to change the way the Divi Vertical Menu submenus appear on desktop. By default the submenus 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).

But we will change it 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.

Watch the quick demo below to see it in action.

Demo

Implementation

To implement this we will use a bit of JS and CSS. CSS will be used to change positioning and styling of submenus and the JS part will make the submenus expand/collapse on 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).

First let’s change the positioning and styling of the submenus. The important point here is that the submenu positioning needs to be changed form 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;
}

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

/* decrease the menu container left and right padding */
.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 accessable due to the fact that the menu does not fit into the screen. To prevent this we need to make the fixed header become scrollable as soon as the menu becomes heigher than the screen.

/* 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;
  }
  
  /* 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!

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 😉

Pin It on Pinterest

Shares
Share This