Bootstrap 5 Offcanvas Menu: When and How to Use It

  • Canvas Team
  • 9 min read
9 min read
Share:

Bootstrap 5 offcanvas menu earns its place, how to implement one correctly, and how to avoid the accessibility and UX pitfalls that trip up even experienced teams.

Key Takeaways

  • Bootstrap 5’s offcanvas component is a slide-in panel controlled by data attributes or JavaScript — no third-party plugins required.
  • Use an offcanvas menu bootstrap pattern for complex, multi-level navigation on mobile, filter panels, and shopping carts — not as a default replacement for a standard navbar.
  • Placement can be left, right, top, or bottom, each suited to different interaction patterns.
  • Accessibility requires correct aria-controls, aria-expanded, and focus-trap behaviour — Bootstrap handles most of this automatically if you follow the markup spec.
  • Combining offcanvas with Bootstrap 5 CSS variables lets you theme the panel without touching core source files.

What Is Bootstrap 5 Offcanvas and How Does It Differ from a Modal?

Introduced as a first-class component in Bootstrap 5, offcanvas is a panel that slides in from any edge of the viewport. At first glance it resembles a Bootstrap 5 modal — both produce an overlay, trap focus, and dismiss on Escape. The crucial differences are:

  • Modal: centred or sized dialogue; designed for confirmations, forms, and focused tasks.
  • Offcanvas: anchored to a viewport edge; designed for navigation, filters, and supplementary content that needs to coexist spatially with the page.

Bootstrap 5 also added a data-bs-scroll attribute that allows the body to remain scrollable while the offcanvas is open — something a modal cannot do without custom overrides. This single feature makes offcanvas the correct choice for persistent filter panels on long listing pages.

When to Use an Offcanvas Menu in Bootstrap

The component earns its complexity cost in a specific set of scenarios. Use it when:

  • Navigation depth exceeds two levels on mobile. A standard .navbar-collapse stacks everything vertically and becomes unwieldy beyond a handful of links. An offcanvas panel gives you the full viewport height and natural scrollability.
  • You need a persistent filter sidebar on a product listing or search results page. The panel can stay open while users scroll results, thanks to data-bs-scroll="true".
  • You are building a mini-cart or quick-view drawer in an e-commerce layout. Right-anchored offcanvas mirrors the mental model users already have from native mobile apps.
  • You have a secondary utility menu — account settings, notifications, help — that should not occupy permanent real estate in the primary navbar.

Do not use offcanvas when a mobile menu bootstrap collapse, a simple dropdown, or a dedicated page would do the job with less JavaScript overhead. Every overlay adds cognitive load; reserve it for cases where the spatial metaphor genuinely aids comprehension.

Basic Implementation: Markup and Data Attributes

The minimal working example requires a trigger element and the panel itself. Bootstrap wires behaviour through data-bs-toggle="offcanvas" and data-bs-target:

<!-- Trigger button -->
<button
  class="btn btn-primary"
  type="button"
  data-bs-toggle="offcanvas"
  data-bs-target="#siteNav"
  aria-controls="siteNav"
>
  Open Menu
</button>

<!-- Offcanvas panel -->
<div
  class="offcanvas offcanvas-start"
  tabindex="-1"
  id="siteNav"
  aria-labelledby="siteNavLabel"
>
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="siteNavLabel">Navigation</h5>
    <button
      type="button"
      class="btn-close"
      data-bs-dismiss="offcanvas"
      aria-label="Close"
    ></button>
  </div>
  <div class="offcanvas-body">
    <ul class="nav flex-column">
      <li class="nav-item"><a class="nav-link" href="/">Home</a></li>
      <li class="nav-item"><a class="nav-link" href="/about">About</a></li>
      <li class="nav-item"><a class="nav-link" href="/services">Services</a></li>
      <li class="nav-item"><a class="nav-link" href="/contact">Contact</a></li>
    </ul>
  </div>
</div>

The .offcanvas-start class anchors the panel to the left edge. Replace it with .offcanvas-end, .offcanvas-top, or .offcanvas-bottom to change placement. No additional JavaScript is needed when the page already loads Bootstrap’s bundle.

Building a Responsive Mobile Menu with Offcanvas

Bootstrap 5.2 introduced responsive offcanvas classes — the most underused feature of the component. Instead of always showing a hamburger button, you can show the full horizontal navbar on wider screens and automatically switch to an offcanvas panel below a breakpoint:

<nav class="navbar navbar-expand-lg bg-body-tertiary">
  <div class="container">

    <a class="navbar-brand" href="/">Brand</a>

    <!-- Toggle visible only below lg -->
    <button
      class="navbar-toggler"
      type="button"
      data-bs-toggle="offcanvas"
      data-bs-target="#mobileNav"
      aria-controls="mobileNav"
      aria-expanded="false"
      aria-label="Toggle navigation"
    >
      <span class="navbar-toggler-icon"></span>
    </button>

    <!-- offcanvas-lg hides panel mechanism on lg+ -->
    <div
      class="offcanvas offcanvas-end"
      tabindex="-1"
      id="mobileNav"
      aria-labelledby="mobileNavLabel"
    >
      <div class="offcanvas-header">
        <h5 class="offcanvas-title" id="mobileNavLabel">Menu</h5>
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
      </div>
      <div class="offcanvas-body">
        <ul class="navbar-nav ms-auto">
          <li class="nav-item"><a class="nav-link" href="/">Home</a></li>
          <li class="nav-item"><a class="nav-link" href="/work">Work</a></li>
          <li class="nav-item"><a class="nav-link" href="/blog">Blog</a></li>
          <li class="nav-item"><a class="nav-link" href="/contact">Contact</a></li>
        </ul>
      </div>
    </div>

  </div>
</nav>

Swap the plain offcanvas class for offcanvas-lg (or offcanvas-md, offcanvas-xl) and Bootstrap will render the panel as a normal inline block above that breakpoint, with zero JavaScript involvement. This pattern pairs cleanly with the spacing and alignment utilities covered in the Bootstrap 5 Navbar: 8 Customisation Patterns guide.

Theming the Offcanvas Panel with CSS Variables

Bootstrap 5’s offcanvas component exposes several CSS custom properties you can override without touching the source Sass. Target the panel directly or scope changes to a parent element:

<style>
  #siteNav {
    --bs-offcanvas-width: 320px;
    --bs-offcanvas-bg: #0d0d0d;
    --bs-offcanvas-color: #f5f5f5;
    --bs-offcanvas-border-color: transparent;
    --bs-offcanvas-transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  }
</style>

If you are working with a Canvas-style design system that uses --cnvs-themecolor, you can reference it directly:

<style>
  #siteNav {
    --bs-offcanvas-bg: var(--cnvs-themecolor);
    --bs-offcanvas-color: #fff;
  }
</style>

For project-wide theming via Sass, the SCSS variables Bootstrap 5 theming guide covers the full variable map in detail.

Accessibility Considerations for Offcanvas Menus

Bootstrap’s offcanvas handles focus trapping and aria-modal automatically when you follow the prescribed markup. There are, however, several things you must handle yourself:

  • Label the panel. Always pair aria-labelledby on the .offcanvas element with a matching id on the .offcanvas-title. Screen readers announce this label when the panel opens.
  • Keep the close button accessible. The aria-label="Close" on .btn-close is not optional — it provides the accessible name for icon-only buttons.
  • Avoid nesting interactive content that is also reachable outside the panel. When the offcanvas is closed, any links or buttons inside it should not be focusable. Bootstrap sets visibility: hidden on the closed state, which removes the elements from the tab order correctly.
  • Test with keyboard navigation. Tab through the open panel, confirm focus does not escape to the page behind the backdrop, and verify that Escape closes the panel and returns focus to the trigger button.

For a broader treatment of accessible interactive components, the Bootstrap 5 accessibility WCAG 2.1 AA guide provides a comprehensive checklist.

Controlling Offcanvas Programmatically

Data attributes cover most use cases, but the JavaScript API is essential when you need to open the panel in response to a custom event — for example, after a form submission or a route change in a single-page application:

<script>
  // Get or create an instance
  const navEl = document.getElementById('siteNav');
  const bsOffcanvas = bootstrap.Offcanvas.getOrCreateInstance(navEl);

  // Open programmatically
  bsOffcanvas.show();

  // Listen for the fully-shown event before moving focus
  navEl.addEventListener('shown.bs.offcanvas', () => {
    navEl.querySelector('.nav-link')?.focus();
  });

  // Close and clean up
  bsOffcanvas.hide();
</script>

The full event lifecycle — show.bs.offcanvas, shown.bs.offcanvas, hide.bs.offcanvas, hidden.bs.offcanvas — mirrors the modal API, so code written for one transfers to the other with minimal changes.

FAQ

A modal is a centred dialogue overlay used for focused interactions such as confirmations, alerts, and forms. An offcanvas panel slides in from a viewport edge and is designed for navigation, filters, and supplementary content. Unlike a modal, offcanvas supports data-bs-scroll="true", allowing the page body to remain scrollable while the panel is open.

Use the responsive offcanvas classes introduced in Bootstrap 5.2: .offcanvas-sm, .offcanvas-md, .offcanvas-lg, or .offcanvas-xl. Below the specified breakpoint the panel behaves as a standard offcanvas drawer; above it, the content is rendered inline as a normal block element. Pair this with a .navbar-toggler wrapped in a .d-lg-none utility class to hide the hamburger button on wider screens.

Yes. Each panel needs a unique id, and each trigger must reference that id via data-bs-target. Bootstrap creates a separate JavaScript instance per element, so panels do not interfere with one another. By default only one panel can be open at a time because Bootstrap closes any open offcanvas before opening a new one, unless you disable the backdrop.

Override the --bs-offcanvas-width CSS custom property on the panel element. For a left or right panel: #myPanel { --bs-offcanvas-width: 400px; }. For top or bottom panels, use --bs-offcanvas-height instead. These overrides require no Sass recompilation and take effect immediately.

The component relies on CSS transitions and a small amount of JavaScript already bundled in Bootstrap’s core bundle, so the marginal performance cost is negligible. The more significant concern is the backdrop layer, which triggers a repaint on open and close. On animation-heavy pages, setting data-bs-backdrop="false" removes the overlay and reduces paint work. For broader performance strategies, see the page speed optimisation guide for Bootstrap 5 templates.

Looking for a production-ready Bootstrap 5 HTML template? Browse Canvas Template demos and find the perfect starting point for your next project.

If you’re working with the Canvas HTML Template and want to generate production-ready layouts faster, try Canvas Builder free and see how much time you save on every project.

Skip the setup — build it free

Spin up a complete Bootstrap 5 site, blog included, with Canvas Builder. No coding, no cost.

Share:
Canvas Team
Canvas Team

Tutorials and tips for building beautiful Bootstrap 5 websites with the Canvas HTML Template and Canvas Builder.

More from the Canvas Blog