NEW  Shrink Screen animation is now available in Elemental Menu. Watch the tutorial →

Dropdown Mega Submenu From Top Screen - Mortar Menu

Published on by in Tutorials.

Yesterday a customer asked me if it’s possible to create a submenu animation similar to the animation on the wearemotto.com website (hover over the “Learn” menu item to see the animation).

It’s quite an attractive mega submenu animation so I decided to make a tutorial about that.

If you want a shortcut, you can download & import this template then paste this JavaScript code into the “Bricks > Settings > Custom Code > Body Footer Scripts” box.

1. The setup

For this tutorial, we need a Sticky Header like this (make sure to enable Sticky else things won’t work):

demo header structure

It’s just a Container of three Columns centered horizontally. All settings of the Container and Columns are default.

Below are the settings for the top-level menu items:

top level menu items settings 1

Set the Horizontal Padding to 0 and set a Gap (whatever value) so that the Undeline Pointer won’t be longer than the menu item labels.

For the Vertical Padding, you can set whatever value you want.

For the Pointer, we will use a dark Underline pointer with Sweep Right animation which is similar to the pointer on the wearemotto.com website.

top level menu items settings 2

Hide the Submenu Indicator as well:

hide the submenu indicator

That’s all with the setup.

2. The mega submenu

You can design the mega submenus however you want. For the tutorial, I created some columns of images and text. Added 40px of the Gap between the columns and 50px of Vertical Padding to the Container.

3. Submenu Backdrop

For convenience & better UX, we will use a custom Submenu Backdrop instead of the background of each submenu.

Above the Horizontal Menu element, add a Block element and a Divider element inside of it:

submenu backdrop element structure

Now select the Divider element and set a margin top which is equal to the height of the header so that it looks like bottom border of the header. For me, it’s 100px:

divider margin top

4. Custom CSS IDs

We need to agree on some CSS IDs so that our JavaScript code can work properly. Below are the elements and their CSS ID:

  • Horizontal Menu element: main-menu
  • Submenu Backdrop element: submenu-backdrop
  • The Header (the outer most Container element): brx-header

5. Custom JavaScript code

Paste the below JavaScript code into the Bricks > Settings > Custom Code > Body Footer Scripts box:

<script type="text/javascript">
window.addEventListener("DOMContentLoaded", () => {
    const topItems = document.querySelectorAll("#main-menu > .mm-container > .brxe-mm-wrapper > .mm-top-item");
    const headerHeight = document.getElementById("brx-header").offsetHeight;
    const submenuBackdrop = document.getElementById("submenu-backdrop");

    if (topItems.length) {
        topItems.forEach(item => {
            item.addEventListener("mouseenter", e => {
                if (item.classList.contains("mm-mega-item")) {
                    document.body.classList.add("hovering-mega-item");
                    const sub = item.querySelector(".mm-mega-sub");
                    submenuBackdrop.style.height = (sub.offsetHeight + headerHeight) + "px";
                    document.body.classList.add("has-active-submenu");
                } else {
                    document.body.classList.remove("has-active-submenu");
                    document.body.classList.remove("hovering-mega-item");
                }
            })
            item.addEventListener("mouseleave", e => {
                document.body.classList.remove("hovering-mega-item");
                setTimeout(() => {
                    if (!document.body.classList.contains("hovering-mega-item")) {
                        document.body.classList.remove("has-active-submenu");
                    }
                }, 300)
            })
        })
    }
});
</script>

The code is to:

  1. Make the height of the Submenu Backdrop adaptive to each mega submenu.
  2. Add a has-active-submenu HTML class to the body when there is an active submenu.

6. Change color of some elements when there is an active submenu

Paste the following code into the Custom CSS box of the Items Wrapper element:

.bricks-is-frontend %root% > .mm-top-item > .mm-mega-sub {
  	background-color: transparent;
  	box-shadow: none;
  	transition-delay: .3s;
}

%root% > .mm-top-item > .mm-item-info::after {
    bottom: 30px;
    transition: transform .4s, background-color .2s;
}

%root% > .mm-top-item > .mm-item-info > .mm-item-link {
    transition-delay: .4s;
}

.has-active-submenu %root% > .mm-top-item > .mm-item-info::after {
    background-color: #fff;
}

.has-active-submenu %root% > .mm-top-item > .mm-item-info > .mm-item-link {
    color: #fff;
    transition-delay: 0s;
}

The code is to:

  1. Remove all submenus’ background color (use the Submenu Backdrop instead).
  2. Customize the Underline pointer of the top-level menu items.
  3. Show the Underline pointer & menu item label with different color when there is an active submenu.

And paste below code into the Custom CSS box of the two Heading elements (on the left & right columns of the Header):

%root% {
    transition: color .2s;
    transition-delay: .4s;
}

.has-active-submenu %root% {
    color: #fff;
    transition-delay: 0s;
}

The code is to:

  1. Timing the time to change the color of the Heading text.
  2. Change color of the Heading text when there is an active subemnu.

Please note that we used Heading text for the Logo on the left and the Call-To-Action on the right. If it’s not text but images instead, you may take a look at these tutorials:

  1. Change text color with JS.
  2. Invert SVG text with GSAP.

And that’s all. The menu should be complete now. If you have any problem or any better ideas, let me know in the comment section. Thanks for reading!