Mobile Menus

Mobile Menus

Below the expand breakpoint, the primary menu collapses behind a hamburger trigger. Canvas provides the trigger button plus a couple of mobile presentation styles (off-canvas, overlay). The same .primary-menu markup is reused; only the trigger and a modifier class are added.

Hamburger Trigger

Place the trigger inside the header row. It toggles the mobile menu open/closed:

<div class="primary-menu-trigger">
	<button class="cnvs-hamburger" type="button" title="Open Mobile Menu">
		<span class="cnvs-hamburger-box">
			<span class="cnvs-hamburger-inner"></span>
		</span>
	</button>
</div>

Mobile Menu Classes

Class Effect
primary-menu-trigger Wrapper for the hamburger button that toggles the mobile menu.
cnvs-hamburger The animated hamburger button itself.
mobile-menu-off-canvas Mobile menu slides in from the side as an off-canvas panel.
mobile-menu-overlay Mobile menu appears as a full-screen overlay.

Off-Canvas Mobile Menu

Add mobile-menu-off-canvas to the .primary-menu. On mobile the menu slides in as a side panel:

<nav class="primary-menu mobile-menu-off-canvas">
	<ul class="menu-container"> ... </ul>
</nav>

<div class="primary-menu-trigger">
	<button class="cnvs-hamburger" type="button" title="Open Mobile Menu">
		<span class="cnvs-hamburger-box"><span class="cnvs-hamburger-inner"></span></span>
	</button>
</div>

Overlay Mobile Menu

<nav class="primary-menu mobile-menu-overlay">
	<ul class="menu-container"> ... </ul>
</nav>

Keeping a Menu Desktop-Only

Use Bootstrap display utilities to show a menu only on large screens (a second menu can then serve mobile):

<nav class="primary-menu top-primary-menu me-2 d-none d-lg-block">
	<ul class="menu-container"> ... </ul>
</nav>

Sticky on Mobile

By default sticky behaviour is desktop-only. To make the header sticky on mobile as well, add data-mobile-sticky="true" to #header:

<header id="header" class="full-header" data-mobile-sticky="true">

Notes and Tips

  • The switch between the desktop menu and the mobile hamburger is governed by the expand breakpoint (body.is-expanded-menu is present on desktop). The hamburger appears when the body is not expanded.
  • Keep the exact three-span structure of .cnvs-hamburger (box > inner); the open/close animation depends on it.
  • Sub-menus in the mobile view expand inline (accordion-style). The .sub-menu-container markup is identical to desktop; no extra classes needed.
  • Use data-responsive-class on #header to apply theme classes (like not-dark) specifically to the mobile layout.

Extras

Custom Menu Breakpoints

The primary menu collapses to the mobile toggle below menuBreakpoint (default 992). Override it per page with data-menu-breakpoint on <body>.

<body class="stretched" data-menu-breakpoint="1200">

Now the full horizontal menu only appears at 1200px and above; below that the burger trigger is used.

To change it globally, set cnvsOptions before functions.bundle.js loads:

<script>
    var cnvsOptions = { menuBreakpoint: 1200 };
</script>
<script src="js/functions.bundle.js"></script>

At or above the breakpoint Canvas adds is-expanded-menu to <body>; below it, that class is removed.

Always Expanded Menus

By default the primary menu collapses into a mobile toggle below the menu breakpoint (992px). To keep a menu always expanded (never collapsing to the burger), lower or disable the breakpoint.

Per page, set the breakpoint to 0 on <body>:

<body class="stretched" data-menu-breakpoint="0">

The body gets the is-expanded-menu class whenever the viewport width is at or above menuBreakpoint, so a value of 0 keeps the full horizontal menu at every width.

Globally, set it in cnvsOptions before functions.bundle.js:

<script>
    var cnvsOptions = { menuBreakpoint: 0 };
</script>

Off-Canvas Mobile Menus

Off-Canvas Mobile Menus

The primary menu can slide in from the side on mobile instead of pushing content down. Add mobile-menu-off-canvas to the .primary-menu. The trigger is the standard hamburger button.

<header id="header">
    <div id="header-wrap">
        <div class="container">
            <div class="header-row">

                <div id="logo">
                    <a href="index.html"><img class="logo-default" src="images/logo.png" alt="Canvas Logo"></a>
                </div>

                <div class="primary-menu-trigger">
                    <button class="cnvs-hamburger" type="button" title="Open Mobile Menu">
                        <span class="cnvs-hamburger-box"><span class="cnvs-hamburger-inner"></span></span>
                    </button>
                </div>

                <nav class="primary-menu mobile-menu-off-canvas ms-auto">
                    <ul class="menu-container">
                        <li class="menu-item"><a class="menu-link" href="#"><div>Home</div></a></li>
                        <li class="menu-item"><a class="menu-link" href="#"><div>About</div></a></li>
                        <li class="menu-item"><a class="menu-link" href="#"><div>Contact</div></a></li>
                    </ul>
                </nav>

            </div>
        </div>
    </div>
</header>

Notes:

  • mobile-menu-off-canvas makes the menu slide in as a panel below the data-menu-breakpoint set on <body> (for example data-menu-breakpoint="1200").
  • Add a direction modifier to control the side it enters from: use off-canvas positioning classes together with the off-canvas menu; the default slides from the left.
  • The menus.js module toggles body classes like primary-menu-open and manages the trigger's active state, so no extra JS is needed.

Alternate Mobile Menu

Canvas supports a separate menu for small screens. Inside a .primary-menu, wrap your normal menu in .menu-container (shown on desktop) and add a second .menu-container.mobile-primary-menu that is revealed only when the mobile trigger is tapped.

<nav class="primary-menu">
    <ul class="menu-container">
        <li class="menu-item"><a class="menu-link" href="#"><div>Home</div></a></li>
        <li class="menu-item"><a class="menu-link" href="#"><div>About</div></a></li>
    </ul>

    <ul class="menu-container mobile-primary-menu">
        <li class="menu-item"><a class="menu-link" href="#"><div>Quick Link 1</div></a></li>
        <li class="menu-item"><a class="menu-link" href="#"><div>Quick Link 2</div></a></li>
    </ul>
</nav>

<button class="primary-menu-trigger">
    <span class="visually-hidden">Menu</span>
    <i class="icon-line-menu"></i>
</button>

When the menu is collapsed (body does not have is-expanded-menu), tapping .primary-menu-trigger toggles d-block on the .mobile-primary-menu block instead of the default .menu-container.

Was this page helpful?