Offcanvas
Offcanvas is a genuinely new component in Bootstrap 5 — it did not exist in Bootstrap 4 at all. It's a hidden panel that slides in from an edge of the screen over the top of the page content, most often used for mobile navigation or, as in the TrailMap example below, a filter sidebar that only needs to be visible while the user is actively narrowing down a trail search.
What Offcanvas Does
Think of it as a modal that slides in from an edge instead of fading in centered on the
screen. Like a modal, it sits above the page, dims the rest of the content with a
backdrop by default, and is opened and closed through data-bs-* attributes
with no custom JavaScript needed for the basic case.
The Four Slide Directions
The base class is .offcanvas, and a second class picks which edge of the
viewport the panel slides in from:
| Class | Slides in from |
|---|---|
.offcanvas-start | The left edge |
.offcanvas-end | The right edge |
.offcanvas-top | The top edge |
.offcanvas-bottom | The bottom edge |
-start and -end rather than -left/-right — Bootstrap 5 uses logical direction names throughout so the same classes work correctly in right-to-left languages.Anatomy: Header, Body, and the Dismiss Button
Internally an offcanvas panel looks a lot like a modal, minus the dialog wrapper:
<div class="offcanvas offcanvas-start" tabindex="-1" id="trailFilters">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Filter Trails</h5>
<button type="button" class="btn-close"
data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
Filter form goes here.
</div>
</div>
Triggering an Offcanvas Panel
Exactly the same pattern as a modal, but with data-bs-toggle="offcanvas"
instead of "modal":
<button class="btn btn-secondary d-md-none" type="button"
data-bs-toggle="offcanvas" data-bs-target="#trailFilters">
<i class="bi bi-funnel"></i> Filters
</button>
The d-md-none utility on the trigger hides the button once the viewport is
wide enough that TrailMap shows the filters as a permanent sidebar instead — offcanvas is
most often reached for specifically as a mobile-width pattern.
Worked Example: TrailMap's Mobile Filter Panel
On narrow screens, TrailMap's trail-listing page swaps its filter sidebar for a left-sliding offcanvas panel containing difficulty, distance, and region filters:
<!-- Trigger, shown only below the md breakpoint -->
<button class="btn btn-outline-secondary d-md-none mb-3" type="button"
data-bs-toggle="offcanvas" data-bs-target="#trailFilters"
aria-controls="trailFilters">
Filter Trails
</button>
<!-- Panel, slides in from the left -->
<div class="offcanvas offcanvas-start" tabindex="-1"
id="trailFilters" aria-labelledby="trailFiltersLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="trailFiltersLabel">Filter Trails</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<h6>Difficulty</h6>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="diffEasy">
<label class="form-check-label" for="diffEasy">Easy</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="diffModerate">
<label class="form-check-label" for="diffModerate">Moderate</label>
</div>
<h6 class="mt-3">Distance</h6>
<input type="range" class="form-range" min="0" max="20" id="distanceRange">
<h6 class="mt-3">Region</h6>
<select class="form-select">
<option>All regions</option>
<option>Pacific Northwest</option>
<option>Rocky Mountains</option>
</select>
<button class="btn btn-primary w-100 mt-4">Apply Filters</button>
</div>
</div>
A hiker on a phone taps "Filter Trails", the panel slides in from the left over a dimmed
backdrop, they narrow down by difficulty/distance/region, then dismiss the panel with the
close button, a click on the backdrop, or the Esc key — all free behavior
that comes from the two data-bs-* attributes on the trigger.