Simple Mega Menus with Beaver Builder and Beaver Themer

I’ve played with a million mega menu plugins over the years – they were all too complex or too simple or was just not user friendly. So I built my own.

I have this saved in my template WordPress install, so that I can easily create a mega menu whenever I want. I’m not going to lie, you can’t be a complete rookie to make mega menus with this code. You need to know about how to create Beaver Themer parts, and set an ID for your rows. If that makes sense to you, then please, right this way….

Watch the video, and then steal the code 🙂

How & Why it Works

  1. Add the ID my-mega-menu to your Beaver Builder menu. – The code will then search this menu for mega menus.
  2. Create a Beaver Themer part, make it visible on the entire site. – This is where we will create the mega menu rows.
  3. Create Rows inside the Themer part – each row is an individual mega menu.
    • For each menu item, create a Row and give the row a special ID. this is where the code does its magic
      • The code takes the menu item name, and looks for a lowercase version, and replaces all non alphanumeric (? ! $ % etc) with a dash , starting with “mega-
      • Contact Us menu item would have an associated mega menu ID of mega-contact-us
      • About maps to mega-maps
      • Services? -> mega-services-
      • Isn’t this it? -> mega-isn-t-this-it
      • weird! things?!# here -> mega-weird-things-here (note the multiple non-alphanumeric in a row characters turn into 1 dash)
      • Stuck? Use the helper function megaDebug() in the console to see all the mega menu row ID’s that you can use.
      • The code does the rest.
  4. On larger screens, the corresponding mega menu will show up under each menu item.
  5. On mobile screens, all the mega menus will be shown, stacked on top of each other when the user clicks the menu/hamburger menu.

The JS:

To add JS sitewide:

  1. Open any page with Beaver Builder
  2. Click the title bar in the upper left corner to open the Tools menu, then click Global settings.
  3. On the JavaScript tab, enter this JavaScript code.
  4. Click Save.
// mega menu js
// with love from https://sitespot.dev/simple-mega-menus-with-beaver-builder-and-beaver-themer/

var menuElement = "#my-mega-menu .menu-item";
var mobileToggle = '.fl-menu-mobile-toggle';

jQuery(document).ready(function(){
  
    // exit if bb is running
    if(jQuery('body').hasClass('fl-builder-edit'))
        return true; 

    //add the helper parent class to the mega menu for mobile
    jQuery('[id^="mega-"]').first().parent().addClass('mega-mobile-container')


    //set top location of 
    jQuery(window).on('resize megamenurefresh', function () {
        if(isMobile())// set init value
        {
            //set top value of container
            topValue = jQuery('header').offset().top + jQuery('header').outerHeight() - 20; 
            jQuery('.mega-mobile-container').css('top',topValue + 'px');
            
        }
        else
        {
            jQuery('.mega-mobile-container').css('top','');
            jQuery('.show-mega-mobile').removeClass('show-mega-mobile');
            topValue = 0;
        }
        
        jQuery(menuElement).each(function(){

            var menuItem = jQuery(this);
            var megaItem = jQuery("#"+"mega-"+menuTitle(menuItem.text()));
            
            if(megaItem.length) // if its  mega anything
            {
                //set up click listeners for menu items 
                menuItem.off('click').click(function(event) {
                    
                    mm = jQuery("#"+"mega-"+menuTitle(jQuery(this).text()));
                    // if it has a mega menu
                    if(mm.length && !isMobile())
                    {
                        event.preventDefault();
                        event.stopPropagation();
                        if(!mm.hasClass('show-mega'))
                        {
                            jQuery('.show-mega').removeClass('show-mega');
                            mm.addClass('show-mega');
                            
                        }
                        else
                            mm.removeClass('show-mega');
                    }
                    
                });

                if(isMobile())
                {
                    megaItem.css('top',  topValue + 'px');
                    topValue += megaItem.height();
                }
                else
                {
                    jQuery('body').removeClass('show-mega-mobile');
                    topValue = jQuery("header").offset().top - jQuery(window).scrollTop() +jQuery("header").outerHeight();
                    megaItem.css('top',  topValue + 'px');
                }
            }
               
        });
    }).resize();
    
    jQuery(mobileToggle).click(function(event){
        event.preventDefault(); // stop the inbuilt stuff from stuffin
        event.stopPropagation();
        jQuery('body').toggleClass('show-mega-mobile');
    });
    
    
    //close mega menu stuff
    
    // escape click    
    jQuery(document).on('keyup', function(e) {
      if (e.key == "Escape")
      {
        jQuery('.show-mega').removeClass('show-mega');
        jQuery('body').removeClass('show-mega-mobile');
      }
    });
    
    //click outside of mega menu
    jQuery(document).on('click', function (e) {
        if (jQuery(e.target).closest('[id^="mega-"], .mega-mobile-container').length === 0) {
            if(jQuery('.show-mega, .show-mega-mobile').length){
                jQuery('[id^="mega-"]').removeClass('show-mega');
                jQuery('body').removeClass('show-mega-mobile');
            }
        }
    });

});


//replace menuItem.text().replace(titleRegex,"-").toLowerCase()
function menuTitle(theText){

    // clean it up

    theText = theText.replace(/[^0-9a-z]/gi, ' ').trim().replace(" ","-").replace(/-{2,}/g, '-');

    return theText.toLowerCase();
}

function isMobile(){
    return (FLBuilderLayoutConfig.breakpoints.small > jQuery(window).width());
}

function megaDebug(){
    jQuery(menuElement).each(function(){
        console.log("mega-"+menuTitle(jQuery(this).text()));
    });
}


EDIT 1: 2 JUN 2021

Changed from on hover to on click. It’s just better 🙂

EDIT 2: 3 JUN 2021

  • Fixed the text parser to replace all non alphanumeric with a dash
  • Added megaDebug() function. Run it in your console to see what your mega menu row ID’s should be.

EDIT 3: 28 SEPT 2021

  • Fixed Regex. Old regex value was getting ‘sanitized’ when saving and breaking the regex. new version doesnt seem to be getting sanitized broken.

The CSS:

To add CSS sitewide:

  1. Open any page with Beaver Builder
  2. Click the title bar in the upper left corner to open the Tools menu, then click Global settings.
  3. On the CSS tab, enter this CSS code.
  4. Click Save.
body:not(.fl-builder-edit) [id^="mega-"] {
    -webkit-transition: all 300ms ease-in-out;
    -moz-transition: all 300ms ease-in-out;
    -ms-transition: all 300ms ease-in-out;
    -o-transition: all 300ms ease-in-out;
    transition: all 300ms ease-in-out;
    z-index: 100;
}
.show-mega{
    visibility: visible !important;
    opacity: 1 !important;
    z-index:101 !important;
}
/* mobile stuffs */
body.show-mega-mobile [id^="mega-"]{
    visibility: visible !important;
    opacity: 1 !important;
}


/* small screens mega settings*/
@media (max-width: 767px){
    
    .mega-mobile-container{
        visibility: hidden;
        opacity: 0;
        position: fixed;
        top:150px;
        left: 0;
        bottom: 0;
        overflow-y: scroll;
        width: 100%;
        z-index: 100;
    }
    
    .show-mega-mobile .mega-mobile-container{
        visibility: visible !important;
        opacity: 1 !important;
    }
    
}
/* bigger screens mega settings*/
@media (min-width: 768px){
    
    body:not(.fl-builder-edit) [id^="mega-"] {
        visibility: hidden;
        opacity: 0;
        position: fixed;
        top:150px;
        left: 0;
        width: 100%;
    }    
    
    
}

Comments:

13 Comments

  1. Ben on June 1, 2021 at 7:21 pm

    Hey there! I love this! So much simpler than some of those menus like Quad Menu.

    Any chance to consider revealing the dropdown on a click?

    https://css-tricks.com/in-praise-of-the-unambiguous-click-menu/

    • Tom on June 1, 2021 at 8:23 pm

      Thanks Ben!

      When you’re right, you’re right. I’ll update the code in the next few days for the unambiguous click.

  2. Craig on June 3, 2021 at 5:03 am

    Hi Tom.

    This is an excellent solution, thank you.

    I have a slight issue in that some of my menu items contain a question mark, which stops the mega menu from working.

    Is there any chance you could update the JS to allow for this please.

  3. Craig on June 3, 2021 at 9:51 am

    Also noticed another issue, I’m getting a gap above each subsequent mega menu…

    Here is a short clip of the issue – https://cln.sh/uFpkhDG1xdAURei758qI

    Unfortunately the site is only on local at the moment, but if you need any further info I can provide it.

  4. Tom on June 3, 2021 at 11:00 am

    Thanks Craig!

    I’ve updated the code to replace all non alphanumeric characters, so your ?’s and !’s should now be replaced with a single “-”

    Just FYI, the code is also updated to on click now, its much better UX than “on hover” 🙂

    I added the helper function megaDebug() so you can see what your mega menu row ID’s should be after being parsed. Just type megaDebug() into the console, and it will tell you the mega names.

    As for the other issue – I can’t really say without seeing it live. Its a good looking site though! Push it onto a server and send me a link, we’ll get it working for you 🙂

    • Craig on June 3, 2021 at 3:14 pm

      Wow! That’s fantastic Tom. Thank you.

      I have emailed you separately with a link and another query.

      Best regards,
      Craig

  5. Heather Steele on June 3, 2021 at 7:08 pm

    This is fantastic! I have been wanting to do just this on a few sites but didn’t have the time or brains to work it out — super excited!

    • Tom on June 8, 2021 at 9:56 am

      Awesome! Please share some links to some completed sites!

  6. Chris Smith on June 15, 2021 at 10:01 am

    Hi Tom –

    Fantastic contribution. Thanks!

    I have a small issue. See:
    https://vsbbusdir.wpengine.com/
    PLAN YOUR TRIP is the mega row and it works great…
    Except when you are on an actual directory listing.

    example:
    https://vsbbusdir.wpengine.com/business-listing/celebration-cruises/
    Now the click doesn’t load the menu rows.

    Can you take a quick look and help me figure it out?

    I am also using the Max Width columns plugin and it too is a great and very much appreciated solution.

  7. Greg on August 5, 2021 at 4:45 pm

    Hi Tom,
    I was using another Mega Menu solution and then found out that it’s really not accessible (specifically via keyboard navigation). Was wondering if your solution here is and if that includes any content in the menu or if it’s only links/button. I.e. if you tab to the top menu item the menu opens, and then you can tab/arrow through all the items in the menu before you tab on to the next top menu item, and so on?

    • Tom on September 16, 2021 at 10:44 am

      Hey Greg!
      This is not accessible as it stands but our next update will be specifically to make it *more* accessible – but definitely not perfect.

  8. David on October 5, 2021 at 4:48 pm

    I love this mega-menu but I”m having a major problem with it and I can’t figure out a solution.

    When I load a page, the mega-menu isn’t visible but it’s sitting behind the regular content just below the menu and the items in my menu are still clickable. This interferes with other interactivity on the page. I would assume that the mega-menu should be positioned off-canvas until it’s needed?

  9. Martin on October 7, 2021 at 11:10 pm

    Great tutorial! Just curious what the JS was to make the menu apper on hover.

Leave a Comment





Level up your Beaver Builder skills

Join 3,264 over Beaver Builders and get our monthly-ish dish

We've got a million ideas that we've implemented on over 300+ BB enabled websites. Pop in your email below, and we'll let you know when a new post or plugin is available :)

Newsletter

  • This field is for validation purposes and should be left unchanged.

Spam sucks.