Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Divi | WordPress Theme | Mobile Menu Collapsible Submenus via Toggles | CSS & jQuery Tweaks in action:
/* -- HEADER -- */
/* remove pointer event from menu module mobile wrapper */
.et_pb_module.et_pb_menu .et_mobile_nav_menu {
pointer-events: none;
/* make menu module hamburger icon and menu links interactive again */
.et_pb_module.et_pb_menu .et_mobile_nav_menu .mobile_menu_bar,
.et_pb_module.et_pb_menu .et_mobile_nav_menu .et_mobile_menu li a {
pointer-events: auto;
/* when mobile menu is open, change hamburger icon to x icon */
#et_mobile_nav_menu .mobile_nav.opened .mobile_menu_bar::before,
.et_pb_module.et_pb_menu .et_mobile_nav_menu .mobile_nav.opened .mobile_menu_bar::before {
content: '\4d';
/* make desktop sub sub menu icon be right arrow instead of down arrow */
#top-menu .menu-item-has-children .menu-item-has-children > a:first-child::after,
#et-secondary-nav .menu-item-has-children .menu-item-has-children > a:first-child::after,
.et_pb_module.et_pb_menu .et-menu .menu-item-has-children .menu-item-has-children > a:first-child::after {
content: '5';
/* if mobile parent link of child menu is a deadlink, then make it not clickable */
#main-header #mobile_menu.et_mobile_menu .menu-item-has-children > a[href="#0"],
.et_pb_module.et_pb_menu .et_mobile_menu .menu-item-has-children > a[href="#0"] {
pointer-events: none;
/* - mobile menu toggling elements, injected via jQuery - */
/* make menu list item be relative, to be able to position toggle within this item */
#main-header #mobile_menu.et_mobile_menu .menu-item-has-children,
.et_pb_module.et_pb_menu .et_mobile_menu .menu-item-has-children {
position: relative;
/* the new toggle element, which is added via jQuery */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle {
position: absolute;
background-color: rgba(0,0,0,0.03);
z-index: 1;
width: 36px;
height: 36px;
line-height: 36px;
border-radius: 50%;
top: 4px;
right: 4px;
cursor: pointer;
text-align: center;
pointer-events: auto;
/* the new toggle element when popped */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle.popped,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle.popped {
background-color: rgba(0,0,0,0.1);
/* toggle icon */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle::before,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle::before {
font-family: "ETmodules" !important;
font-weight: normal;
font-style: normal;
font-variant: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 36px;
font-size: 24px;
text-transform: none;
speak: none;
content: '\33';
/* toggle icon when triggered */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle.popped::before,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle.popped::before {
content: '\32';
/* hide sub menus by default */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle ~ ul.sub-menu,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle ~ ul.sub-menu {
display: none !important;
padding-left: 0;
/* show sub menu when triggered via jQuery toggle, and add slight bg color */
#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle.popped ~ ul.sub-menu,
.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle.popped ~ ul.sub-menu {
display: block !important;
background-color: rgba(0,0,0,0.03) !important;
/* remove sub menu list item left padding, since padding will be on anchors */
#main-header #mobile_menu.et_mobile_menu li li,
.et_pb_module.et_pb_menu .et_mobile_menu li li {
padding-left: 0;
/* adjust mobile menu anchors side paddings */
#main-header #mobile_menu.et_mobile_menu li a,
.et_pb_module.et_pb_menu .et_mobile_menu li a {
padding-left: 20px;
padding-right: 20px;
/* indent sub menu */
#main-header #mobile_menu.et_mobile_menu li li a,
.et_pb_module.et_pb_menu .et_mobile_menu li li a {
padding-left: 40px;
padding-right: 20px;
/* indent sub sub menus further */
#main-header #mobile_menu.et_mobile_menu li li li a,
.et_pb_module.et_pb_menu .et_mobile_menu li li li a {
padding-left: 60px;
padding-right: 20px;
/* if mobile menu anchor has toggle, make room for it to fit next to the link */
#main-header #mobile_menu.et_mobile_menu .menu-item-has-children .sub-menu-toggle + a,
.et_pb_module.et_pb_menu .et_mobile_menu .menu-item-has-children .sub-menu-toggle + a {
padding-right: 44px;
/* - end mobile menu toggling elements - */
/* undo Divi's default styling of mobile menu links that have children */
#main-header #mobile_menu.et_mobile_menu .menu-item-has-children > a,
.et_pb_module.et_pb_menu .et_mobile_menu .menu-item-has-children > a {
background-color: transparent;
font-weight: inherit;
/* make the current page's mobile menu link be different */
#main-header #mobile_menu.et_mobile_menu li.current-menu-item > a,
.et_pb_module.et_pb_menu .et_mobile_menu li.current-menu-item > a {
font-weight: bolder;
/* -- END HEADER -- */
jQuery( document ).ready( function( $ ) {
// Create collapsible sub menus in mobile Divi Header Nav
$( '<div class="sub-menu-toggle"></div>' ).insertBefore( '#main-header #mobile_menu.et_mobile_menu .menu-item-has-children > a' );
// Create collapsible sub menus in mobile Divi Theme Builder Menu
$( '<div class="sub-menu-toggle"></div>' ).insertBefore( '.et_pb_module.et_pb_menu .et_mobile_menu .menu-item-has-children > a' );
// Toggle the class to be popped on mobile Divi Header Nav
$( '#main-header #mobile_menu.et_mobile_menu .sub-menu-toggle' ).click(function () {
// Toggle the class to be popped on mobile Divi Theme Builder Menu
$( '.et_pb_module.et_pb_menu .et_mobile_menu .sub-menu-toggle' ).click(function () {
// Replace the mobile Divi Theme Builder Menu toggle with different href other than # hash, to prevent scroll to top on sub-menu-toggle clicks
$( '.et_pb_module.et_pb_menu a.mobile_nav[href="#"]' ).attr( 'href', '#0' )
} );
Copy link

Garconis commented Feb 24, 2017

Add styles (without <style> tags) to your child theme CSS file
Add script (with <script> tags) to Divi Theme Options > Integrations > Body area

You may need to tweak the /* toggle icon */ font color and size of the toggle element, based on your colors and typeface.

Copy link

rezl commented Apr 1, 2017

This is great! I'm assuming there's no easy way to make the parent-items clickable as well? Ubermenu does ths, but I've noticed many menus seem to not allow top-level navigation items to be pages as well (making the toggle and text perform different actions).

Copy link

Garconis commented Jun 7, 2017

@rezl , did you try this out? The parent menu items are clickable. That's one of the main reason I created this, instead of using other options I've stumbled upon.

Copy link

VRHex commented Jun 16, 2019

great! thx, dude!

Copy link

jeffpaterson commented Feb 25, 2020

This is awesome. Worked perfectly. Huge improvement over default Divi mobile menu. Three years after you shared this, how has ET not made this standard?

Copy link

danishishfaq commented Mar 11, 2020

I Dont know how to thank you man.
Perfectly working thanks again.
the code in divi documentation is useless
Awesome Job

Copy link

maumbury commented May 17, 2020

Thank-you. It was annoyances like this that made me ditch DIVI but still have old sites that need updates and this was a welcome find.

Copy link

blackbird8552 commented May 20, 2020

Hi code works great although I have quite a lot of sub menus is it possible to have them closed as currently each main menu item and its sub menus are open. Your assistance would be much appreciated.

Copy link

Azim-Munna commented May 23, 2020

thanks man <3 get love from me <3

Copy link

rr-gs commented Aug 13, 2020

Hello. I really want this to work, but it doesn't.

On this tutorial page, Sandra says this:

Jon, your solution is exactly what I’m looking for. Unfortunately since the navigations are now built in the theme builder some classes and IDs how now changed from your original code – i.e. #main-header and #top-menu. Any solution for the theme builder, pretty please with a cherry on top ?🙏

Is there any truth to this? Does this need to be updated due to classes and ID names?

Copy link

Garconis commented Aug 15, 2020

Any solution for the theme builder, pretty please with a cherry on top ?🙏

Is there any truth to this? Does this need to be updated due to classes and ID names?

@rr-gs yes, this did not work with Theme Builder since they used different classes and structure. I've now updated this and tested on desktop and mobile devices. It should now work for both the regular Divi header menu, and Menu Modules within the Theme Builder.

Copy link

rr-gs commented Aug 17, 2020

Thanks. I appreciate you going to the effort. It's not working for me. I don't think my site has any of the IDs used in this code, based on searching Console. Something isn't lining up for me. I'll take a closer look, but thanks for doing this.

Copy link

rr-gs commented Aug 17, 2020

I ended up using this solution:

I'm not sure how it lines up with this code, but it worked for me.

Copy link

Garconis commented Aug 17, 2020

@rr-gs are you able to share your domain with me to see what the issue may be? I tested in Theme Builder, and it worked fine on a base install with Divi.

Copy link

Augustin974 commented Aug 22, 2020

Thanks, but that doesn't works for me, i use menu built in theme builder.

Copy link

ls-sol commented Jul 30, 2021

Oh wow @Garconis, thank you so much for this code.
This is finally the solution that works like I intended. Great job!

I've only got one last questions I couldn't solve so far:
Imagine I'm on a subsite an now open the menu again. Is it possible to open the menu with the active section already opened, so users can see where they currently are?

Thank you so much in advance.

Copy link

jason-hub commented Oct 23, 2021

Neither this solution nor works in the latest version of Chrome for Mac. The +/x icons either make the entire menu collapse when clicked or they don't appear at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment