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
| Class | Result |
|---|---|
| offcanvas-start | Slides in from the left |
| offcanvas-end | Slides in from the right |
| offcanvas-top | Slides down from the top |
| offcanvas-bottom | Slides up from the bottom |
| offcanvas-sm / -md / -lg | Behaves as a normal block above the breakpoint, offcanvas below it |
| show | Panel starts open (rarely wanted) |
| JavaScript option | Default | Use |
|---|---|---|
| backdrop | true | Set false to keep the page clickable behind the panel |
| keyboard | true | Escape closes the panel when true |
| scroll | false | Allow 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-targetor 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:falsethe body is locked; add scrolling insideoffcanvas-bodyinstead.
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.

