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-menuis 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-containermarkup is identical to desktop; no extra classes needed. - Use
data-responsive-classon#headerto apply theme classes (likenot-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-canvasmakes the menu slide in as a panel below thedata-menu-breakpointset on<body>(for exampledata-menu-breakpoint="1200").- Add a direction modifier to control the side it enters from: use
off-canvaspositioning classes together with the off-canvas menu; the default slides from the left. - The
menus.jsmodule toggles body classes likeprimary-menu-openand 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.
