Quick answer: A Bootstrap 5 offcanvas is a slide-out panel built from a div.offcanvas with a placement class such as offcanvas-start, offcanvas-end, offcanvas-top or offcanvas-bottom. Open it with a button carrying data-bs-toggle="offcanvas" and data-bs-target matching the panel id. It is the modern replacement for a hand-built slide-out menu — responsive, focus-trapped and keyboard accessible out of the box. Give it a unique id and a matching target, or the trigger will do nothing.

Part of our Bootstrap series. If you have not set the framework up yet, start with getting started with Bootstrap 5.

A working offcanvas in one block

This example opens a navigation drawer from the left. Everything below the trigger button is reusable markup you can put in a template partial.

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

<!-- Panel -->
<div class="offcanvas offcanvas-start" tabindex="-1" id="menu"
     aria-labelledby="menuLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="menuLabel">Menu</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="/blog/">Blog</a></li>
    </ul>
  </div>
</div>

The tabindex="-1" on the panel is required. Bootstrap moves focus into the drawer when it opens and returns focus to the trigger when it closes; without the tab index the focus trap fights the page. The btn-close inside the header carries data-bs-dismiss="offcanvas", which handles closing without any JavaScript of your own.

Placement and option reference

ClassResult
offcanvas-startSlides in from the left
offcanvas-endSlides in from the right
offcanvas-topSlides down from the top
offcanvas-bottomSlides up from the bottom
offcanvas-sm / -md / -lgBehaves as a normal block above the breakpoint, offcanvas below it
showPanel starts open (rarely wanted)
JavaScript optionDefaultUse
backdroptrueSet false to keep the page clickable behind the panel
keyboardtrueEscape closes the panel when true
scrollfalseAllow scrolling the page body while open

Responsive navigation pattern

The most common real use is a mobile menu that becomes a normal top bar on desktop. Combine the responsive placement class with a navbar and the same markup serves both breakpoints.

<nav class="navbar bg-body-tertiary">
  <div class="container-fluid">
    <button class="navbar-toggler" type="button"
            data-bs-toggle="offcanvas" data-bs-target="#nav"
            aria-controls="nav" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="offcanvas offcanvas-end" tabindex="-1" id="nav">
      <div class="offcanvas-header">
        <h5 class="offcanvas-title">Site</h5>
        <button type="button" class="btn-close"
                data-bs-dismiss="offcanvas"></button>
      </div>
      <div class="offcanvas-body">
        <ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
          <li class="nav-item"><a class="nav-link" href="/">Home</a></li>
        </ul>
      </div>
    </div>
  </div>
</nav>

The navbar’s built-in toggle logic still applies, so the button collapses the menu on small screens exactly as a standard navbar would. If your navigation is a classic collapse instead of a drawer, the Bootstrap navbar guide shows that pattern in full.

Common mistakes

  • Missing id. Every offcanvas needs a unique id that a data-bs-target or a dismiss button points at.
  • Using it for large content. Offcanvas is for menus and short forms; long pages belong in a modal or a real page.
  • Two panels with the same id. Duplicated ids open the wrong drawer or none at all.
  • Forgetting tabindex="-1". Focus management breaks without it.
  • Expecting it to scroll. With the default scroll:false the body is locked; add scrolling inside offcanvas-body instead.

Offcanvas, modal and accordion all use the same data-attribute API, so once you know one you know the others. For a centred dialog rather than an edge panel, see the modal guide, and for a dropdown menu read the dropdown guide. If you are building the surrounding grid, the Bootstrap 5 grid guide keeps the pieces aligned.

Building a responsive shell and want a second pair of eyes? Ampersand Academy teaches front-end development one-to-one, using your own project as the curriculum.

Frequently asked questions

What is the difference between a Bootstrap offcanvas and a modal?

An offcanvas slides in from an edge and is meant for menus and side panels. A modal appears centred over a backdrop and is meant for focused tasks and confirmations. Both share the same data-attribute API.

How do I close a Bootstrap offcanvas from my own button?

Add data-bs-dismiss to the button with a value of offcanvas. Any element carrying that attribute closes the open offcanvas without extra JavaScript.

Can I make a Bootstrap offcanvas appear only on mobile?

Yes. Use a responsive class such as offcanvas-md or offcanvas-lg. Below the breakpoint it behaves as an offcanvas panel, and at or above it the same markup renders as normal inline content.

How do I open a Bootstrap offcanvas from JavaScript?

Call bootstrap.Offcanvas.getOrCreateInstance with the panel element, then the show method. The hide method closes it and toggle flips between the two states.

Why does my page not scroll while the offcanvas is open?

The default scroll option is false, so the page body is locked to keep focus on the panel. Set the scroll option to true when initializing it if you need the background page to scroll.