HubSpot CMS

Hubspot Mobile Menu

This is a menu designed to work with the hubspot default menu system. It currently is only good for 2 levels of menu but can be expanded from there.

Created by: Chad Pierce

Tags: Menus and navigation

Unverified
?

After receiving a minimum of 25 recommendations, an entry earns the "Community Approved" badge.

Please keep in mind, all entries are community created and may not be fully supported by HubSpot.

3 Recommendations

View on:

GitHub

HTML + HUBL
          
            <!-- HTML & HubL code goes here -->
<!--

	The only HTML you need is the wrapper class you are using for the main menu and the link class for the logo
	My scripts and css does the rest

 -->


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="style.css">
</head>
<body>
	<!-- // Logo HTML -->
	<!-- // Menu HTML -->

	 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
	 <script src="plugin.js"></script>
	 <script src="yourscripts.js"></script>
</body>
</html>
          
        
CSS
          
            /* HUBSPOT MOBILE MENU */
/* If you want to remove the css variables just
   replace the var name with the corrolatring color. */

   :root {
     --white: #fff;
     --color1: #4168b1;
     --color2: #eee;
     --color3: rgba(33, 59, 110, 0.9);
     --color4: #252525;
     --color5: rgba(0, 0, 0, .25);
     
   }
   *,*:before, *:after {
   		box-sizing: border-box;
   }
   .main-menu, .courtesy-menu {
     display: none !important;
   }
   .mobile-menu {
     display: block;
     overflow: auto;
     margin: 0 !important;
     position: fixed;
     top: 0;
     bottom: 0;
     left: 0;
     height: 100vh;
     width: 100%;
     max-width: 300px;
     background: var(--white);
     z-index: 2010;
     transform: translateX(-200%);
     transition: transform 0.25s cubic-bezier(1, -0.06, 0, 0.92);
   }
   .mobile-menu .logo {
     display: block;
     padding: 1rem;
     margin: 0;
     text-align: center;
     color: var(--color1);
   }
   .mobile-menu .logo svg {
     height: 80px;
   }
   .mobile-menu > ul {
     font-size: 0.8em;
     background: var(--color2);
   }
   .mobile-menu > ul a {
     padding: 0.25rem 1rem;
     font-size: 16px;
     line-height: 27px;
   }
   .mobile-menu > ul {
     display: block;
     padding: 0;
     margin: 0;
     list-style: none !important;
   }
   .mobile-menu > ul > li {
     display: block;
     width: 100%;
     border-bottom: 1px solid var(--color2);
   }
   .mobile-menu > ul > li > a {
     display: block !important;
     padding: 1em !important;
     white-space: inherit !important;
     max-width: 100% !important;
     text-overflow: inherit !important;
     line-height: auto;
     text-decoration: none;
     color: var(--color4);
     border-top: 3px solid transparent;
   }
   .mobile-menu > ul > li:hover > a,
   .mobile-menu > ul > li.active > a {
     color: var(--white);
     background-color: var(--color1);
   }
   .mobile-menu > ul > li > ul {
     display: block !important;
     position: relative !important;
     opacity: 1 !important;
     visibility: inherit !important;
     max-height: 0px;
     background: var(--color3);
     border-top: 0 none;
     box-shadow: none;
     overflow: hidden;
     list-style: none;
     margin: 0;
     padding: 0;
     -webkit-transition: max-height 0.125s ease-in-out !important;
     transition: max-height 0.125s ease-in-out !important;
   }
   .mobile-menu > ul > li > ul li a {
     padding: 0.5em 1em !important;
     width: 100% !important;
     color: var(--white);
     display: block;
     text-decoration: none;
   }
   .mobile-menu .hs-item-has-children {
     float: none !important;
   }
   .mobile-menu .hs-item-has-children:after {
     content: "";
     display: table;
     width: 100%;
     height: 0;
     clear: both;
   }
   .mobile-menu .hs-item-has-children > * {
     -webkit-box-flex: 1;
     -webkit-flex: 1 100%;
     -ms-flex: 1 100%;
     flex: 1 100%;
   }
   .mobile-menu .hs-item-has-children > a {
     display: inline-block;
     float: left;
     width: 80%;
   }
   .mobile-menu .hs-item-has-children > button {
     display: inline-block;
     float: left;
     width: 20%;
     line-height: 60px;
     border: 0 none;
     background: var(--color2);
     -webkit-appearance: none !important;
     outline: none !important;
   }
   .mobile-menu .hs-item-has-children > button svg {
     height: 16px;
     width: 16px;
   }
   .mobile-menu .hs-item-has-children > button.active {
     background: var(--color3);
   }
   .mobile-menu .hs-item-has-children > button.active svg {
     transform: rotate(180deg);
     fill: var(--white);
   }
   .mobile-menu .hs-item-has-children > button.active + ul {
     max-height: 1000px !important;
   }
   .mobile-menu .hs-item-has-children > ul.hs-menu-children-wrapper {
     width: 100%;
     display: block;
   }
   .mobile-menu .hs-item-has-children > ul.hs-menu-children-wrapper ul {
     display: none;
   }
   .menu-overlay {
     opacity: 0;
     -webkit-transition: opacity 0.5s ease-in-out;
     transition: opacity 0.5s ease-in-out;
   }
   .mobileMenuTrigger {
     display: block;
     border: 0 none;
     outline: none;
     position: fixed;
     padding: 5px;
     top: 1rem;
     right: 1rem;
     z-index: 2020;
     height: 50px;
     background: var(--white);
     width: auto;
     box-shadow: 0 15px 25px var(--color5);
   }
   .mobileMenuTrigger:focus {
     outline: none;
   }
   .mobileMenuTrigger svg {
     fill: var(--color3);
     width: 40px;
     height: 40px;
   }
   .menu-open {
     overflow: hidden;
   }
   .menu-open .mobile-menu {
     -webkit-transform: translateX(0);
     transform: translateX(0);
   }
   .menu-open .menu-overlay {
     background: var(--color3);
     position: fixed;
     top: 0;
     right: 0;
     height: 100vh;
     left: 0;
     z-index: 2000;
     opacity: 1;
   }
   .menu-open .mobileMenuTrigger {
     position: fixed;
     left: calc(300px + .25em);
     top: 1rem;
     right: 1rem;
     background: transparent;
     box-shadow: 0 0 0 transparent;
   }
   .menu-open .mobileMenuTrigger svg {
     fill: var(--white);
   }
   .hs-menu-depth-2.hs-item-has-children ul {
     display: none;
   }
   @media screen and (min-width: 768px) {
     .courtesy-menu, .main-menu {
       display: block !important;
     }
     .mobileMenuTrigger, .mobile-menu, .main-menu .hs-item-has-children > button {
       display: none;
     }
   }



          
        
JS
          
            //////////////////////////////////////////////////////////////////////////////
//
// Mobile Menu
//
//////////////////////////////////////////////////////////////////////////////  

// menuWrapper = a comma seperated list of classes you gave the wrapper for the menus of your website you want in your mobile menu.
// logo = logo anchor link if you want it to be clickable.

function mobileMenu(menuWrapper, logo) {

    var $windowWidth = $(window).width(),
        $mainMenu = $(menuWrapper),
        $mobileMenuLocal = $('body').prepend('<nav class="mobile-menu"></nav>'),
        $mobileMenuOverlay = $('body').append('<div class="menu-overlay"></div>'),
        $mobileMenu = $('.mobile-menu'),
        $menuSVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M436 124H12c-6.6 0-12-5.4-12-12V80c0-6.6 5.4-12 12-12h424c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12zm0 320H12c-6.6 0-12-5.4-12-12v-32c0-6.6 5.4-12 12-12h424c6.6 0 12 5.4 12 12v32c0 6.6-5.4 12-12 12zM83.4 201.7h33.8V314h-22v-76c0-2.2 0-5.2.1-9.2.1-3.9.1-7 .1-9.1L74.1 314H51.3l-21.1-94.2c0 2.1 0 5.2.1 9.1 0 3.9.1 7 .1 9.2V314H8.5V201.7h34.1L63.1 290l20.3-88.3zM221.8 221.6h-59.4v23.8H217v19.5h-54.5v28.9h62.1V314h-85.1V201.7h82.3v19.9zM242.5 201.7h24.6l44.6 78.3v-78.3h21.9V314H310l-45.7-79.7V314h-21.9V201.7zM355.5 201.7h23.8v68.9c0 7.7.9 13.3 2.7 16.9 2.8 6.3 9 9.4 18.5 9.4s15.6-3.1 18.4-9.4c1.8-3.6 2.7-9.2 2.7-16.9v-68.9h23.8v69c0 11.9-1.9 21.2-5.6 27.9-6.9 12.2-20 18.3-39.5 18.3s-32.6-6.1-39.5-18.3c-3.7-6.7-5.5-15.9-5.5-27.9v-69z"/></svg>',
        $closeSVG = '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 384 512"><path d="M231.6 256l130.1-130.1c4.7-4.7 4.7-12.3 0-17l-22.6-22.6c-4.7-4.7-12.3-4.7-17 0L192 216.4 61.9 86.3c-4.7-4.7-12.3-4.7-17 0l-22.6 22.6c-4.7 4.7-4.7 12.3 0 17L152.4 256 22.3 386.1c-4.7 4.7-4.7 12.3 0 17l22.6 22.6c4.7 4.7 12.3 4.7 17 0L192 295.6l130.1 130.1c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17L231.6 256z"/></svg>',
        $chevronArrow = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"/></svg>';

    // if main menu doesnt exist.
    if ($mainMenu.length > 0) {
        // Add Hamburger Menu on mobileMenu() Init
        $mobileMenu.before('<button class="mobileMenuTrigger open">' + $menuSVG + '</button>');
    }

    // clone and append the main menu to a off canvas menu
    var migrateMenu = $mainMenu.find('.hs-menu-wrapper > ul')
        .clone()
        .addClass(function(index) {
            // add classes to each individual menu source
            var menu = 'menu-' + index
            return menu;
        })
        .appendTo($mobileMenu);


    // Add logo To Mobile Menu If True
    if (logo !== '') {
        var $logoClone = $(logo).eq(0).clone().addClass('logo');
        $mobileMenu.prepend($logoClone); // add class of logo to it
    }

    // add buttons to parent menu items
    $mobileMenu.find('.hs-menu-depth-1.hs-item-has-children > ul')
        .before('<button>' + $chevronArrow + '</button>')

    // add click function for dropdowns
    $mobileMenu.find('.hs-item-has-children > button').on('click', function() {
        var isActive = $(this).hasClass('active');
        switch (isActive) {
            case true:
                $(this).toggleClass('active');
                break;
            default:
                $('.hs-item-has-children > button').removeClass('active');
                $(this).toggleClass('active');
        }
    });

    // Add Click To Open / Close Menu
    $('html').on('click', '.mobileMenuTrigger.open', function() {
        $('body').addClass('menu-open');
        $(this).removeClass('open')
            .addClass('close')
            .html($closeSVG);
    });
    $('html').on('click', '.mobileMenuTrigger.close', function() {
        $('body').removeClass('menu-open');
        $(this).removeClass('close')
            .addClass('open')
            .html($menuSVG);
    });

    // Close mobile menu when you click on the .menu-overlay
    $('html').on('click', '.menu-overlay', function() {
        $('body').removeClass('menu-open');
        $('.mobileMenuTrigger.close').removeClass('close')
            .addClass('open')
            .html($menuSVG)
    });

    // Do Stuff On Resize
    $(window).on('resize', function() {
        $windowWidth = $(window).width();
        if ($windowWidth > 1024) {
            $('body').removeClass('menu-open');
        }
    });

}
          
        
Have Questions?

Ask technical questions in Slack.

HubSpot Developer Slack

Not a member yet? - join here
READ ME (VIEW IN GITHUB)

Mobile Menu For Hubspot Websites

A mobile menu designed to work with the hubspot framework.

Installation

Add the plugins.js to your template. Then add the app.js to your template below the plugins file.

Once those two files are added change the mobileMenu script to match the classes you are using fo rthe menu and the logo of your website. mobileMenu('.menu-wrapper','.logo-class')

if you do not wish to add a logo to the menu you can just leave that part out. menuMobile('.menu-wrapper')

If you have a secondary menu you would like to add you can do so by seperating its wrapper with a comma like so: menuMobile('.courtesy-menu-wrapper, .main-menu-wrapper', '.logo-class')

Styles

The syles are added via the style.css file. You can add those css styles to your current stylesheet as well.

To change colors please just change this block.

    :root {
        --white: #ffffff;
        --color1: #4168B1;
        --color2: #EEEEEE;
        --color3: rgba(33, 59, 110, 0.9);
        --color4: #252525;
        --color5: rgba(0,0,0,.25);
    }

Future Additions

This menu is only good for 2 levels currently which is all I usually use. I will be updating it to include unlimited levels soon.

 
3 Recommendations

Chad Pierce

A Design Link

8+ Years developing on the HubSpot CMS. Javascript/HTML/CSS and design.

View Chad Pierce’s Gallery (1 Entry)

Contribute to the Gallery!

We bet you’ve coded some amazing stuff. Showcase them and help the community grow.

Contribute

Other Open Source Projects

Browse all other open source projects

CrankShaft Framework

A modern framework for accelerating build times on the HubSpot CMS. Based on a modified Bootstrap 4 framework.

Lead developers: Jon McLaren

Developer Chrome Extension

Chrome/Chromium extension for HubSpot CMS Developers that adds a developer menu, dark theme and useful shortcuts to commonly used HubSpot query parameters, resources, and tools for making HubSpot Development easier and more enjoyable.

Lead developers: Jon McLaren , William Spiro , Gonzalo Torreras

VS Code HubL Language Extension

This extension enables super fast local development of CMS pages, and is a great compliment to using the new local HubL server. It contains comprehensive HubL tag, function, filter and expression test auto-complete snippets, as well as their documentation.

Lead developers: William Spiro

Not coding on HubSpot CMS yet?

We invite you to explore why thousands of developers LOVE coding with HubSpot!

Contribute
Made with  by community members: InboundLabs.co