Offcanvas
An offcanvas is a hidden panel that slides in from the edge of the screen, for navigation, filters or settings.
An offcanvas is a panel that slides in from the left, right, top or bottom edge of the viewport. A button or a link with data-bs-toggle="offcanvas" and data-bs-target opens it, and Bootstrap's JavaScript does the rest.
Basic usage
Add the .offcanvas class to the panel and one of .offcanvas-start, .offcanvas-end, .offcanvas-top or .offcanvas-bottom for the edge it slides in from. Bootstrap adds the .show class while the panel is open.
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas" aria-label="Sidebar" data-bs-scroll="true">
<div class="offcanvas-body"> Content for the offcanvas goes here. You can place just about any Tabler component or custom elements here. </div>
</div>Header, title and footer
Split the panel into offcanvas-header, offcanvas-body and offcanvas-footer. The header takes a bottom border and holds the title and the close button; the footer keeps the same padding as the body, which suits the buttons that close the panel.
Use offcanvas-title for the heading, and point the panel's aria-labelledby at its id so the panel is announced by name.
Filters
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-header" aria-labelledby="offcanvas-header-label">
<div class="offcanvas-header">
<h2 class="offcanvas-title" id="offcanvas-header-label">Filters</h2>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">Pick the filters you want to apply.</div>
<div class="offcanvas-footer">
<button type="button" class="btn btn-primary w-100">Apply</button>
</div>
</div>Narrow panel
Add offcanvas-narrow for a panel thinner than the default. It suits a short list of filters or settings, where the full width would leave the panel mostly empty.
Filters
<div class="offcanvas offcanvas-end offcanvas-narrow" tabindex="-1" id="offcanvas-narrow" aria-labelledby="offcanvas-narrow-label">
<div class="offcanvas-header">
<h2 class="offcanvas-title" id="offcanvas-narrow-label">Filters</h2>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">Pick the filters you want to apply.</div>
<div class="offcanvas-footer">
<button type="button" class="btn btn-primary w-100">Apply</button>
</div>
</div>Floating panel
Add offcanvas-floating to keep a gap between the panel and the edges of the screen. The panel gets a border on every side and rounded corners, so it looks like a card over the page. It works with every direction and with the responsive offcanvas-{breakpoint} classes.
Settings
<div class="offcanvas offcanvas-end offcanvas-floating" tabindex="-1" id="offcanvas-floating" aria-labelledby="offcanvas-floating-label">
<div class="offcanvas-header">
<h2 class="offcanvas-title" id="offcanvas-floating-label">Settings</h2>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">The panel does not touch the edges of the screen.</div>
</div>The gap is 0.5rem by default. Change it with the --tblr-offcanvas-margin variable, or with $offcanvas-margin in SCSS.
To float every panel on the page without touching the markup, set data-bs-offcanvas-style="floating" on <html>.
Cookies banner
An offcanvas at the bottom edge also works as a cookie banner. It stays visible until the user answers, and it doesn't cover the page.
<div class="offcanvas offcanvas-bottom h-auto" tabindex="-1" id="offcanvasBottom" aria-modal="true" role="dialog" data-bs-scroll="true">
<div class="offcanvas-body">
<div class="container">
<div class="row align-items-center">
<div class="col">
<strong>Do you like cookies?</strong> 🍪 We use cookies to ensure you get the best experience on our website. <a href="#">Learn more</a>
</div>
<div class="col-auto">
<button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Essential Cookies Only </button>
</div>
<div class="col-auto">
<button type="button" class="btn btn-primary" data-bs-dismiss="offcanvas"> Allow All Cookies </button>
</div>
</div>
</div>
</div>
</div>Accessibility
- Point
aria-labelledbyat the offcanvas title so the panel is announced by name. - Bootstrap moves focus into the panel, keeps it there while the panel is open, and returns it to the trigger on close. That depends on
tabindex="-1"being on the offcanvas element. - The toggle needs
aria-controlswith the panel id. Bootstrap managesaria-expandeditself. - Escape closes the panel unless you set
data-bs-keyboard="false". If you do turn it off, keep a visible close button. - Content behind the panel stays in the DOM. Use the backdrop, which Bootstrap marks
aria-hidden, rather than building your own overlay.
Class reference
Every class this component ships, grouped by what it changes. A name in braces stands for a family — {color} is any base color, {breakpoint} any responsive step.
offcanvas | component | Container element, hidden until Bootstrap opens it |
offcanvas-header | part | Title bar with a bottom border |
offcanvas-title | part | Heading inside the header |
offcanvas-body | part | Content area |
offcanvas-footer | part | Row of actions at the bottom |
offcanvas-narrow | modifier | Narrower panel, 20rem instead of the default width |
offcanvas-floating | modifier | Keeps a 0.5rem gap between the panel and the viewport edges |
offcanvas-start | direction | Slides in from the leading edge |
offcanvas-end | direction | Slides in from the trailing edge |
offcanvas-top | direction | Slides in from the top |
offcanvas-bottom | direction | Slides in from the bottom |
offcanvas-{breakpoint} | size | Behaves as an offcanvas below the breakpoint and as normal content above it |
CSS
Variables
The component uses local CSS variables on %offcanvas-css-vars for real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too. Source: core/scss/bootstrap/_offcanvas.scss.
--offcanvas-zindex: #{$zindex-offcanvas};
--offcanvas-width: #{$offcanvas-horizontal-width};
--offcanvas-height: #{$offcanvas-vertical-height};
--offcanvas-padding-x: #{$offcanvas-padding-x};
--offcanvas-padding-y: #{$offcanvas-padding-y};
--offcanvas-margin: #{$offcanvas-margin};
--offcanvas-color: #{$offcanvas-color};
--offcanvas-bg: #{$offcanvas-bg-color};
--offcanvas-border-width: #{$offcanvas-border-width};
--offcanvas-border-color: #{$offcanvas-border-color};
--offcanvas-box-shadow: #{$offcanvas-box-shadow};
--offcanvas-transition: #{transform $offcanvas-transition-duration ease-in-out};
--offcanvas-title-line-height: #{$offcanvas-title-line-height};Sass variables
Override these variables before importing Tabler to change the defaults. Source: core/scss/_variables.scss.
$offcanvas-padding-y: $modal-inner-padding;
$offcanvas-padding-x: $modal-inner-padding;
$offcanvas-horizontal-width: 400px;
$offcanvas-vertical-height: 30vh;
$offcanvas-transition-duration: 0.3s;
$offcanvas-border-color: var(--border-color);
$offcanvas-border-width: $modal-content-border-width;
$offcanvas-title-line-height: $modal-title-line-height;
$offcanvas-bg-color: var(--bg-surface);
$offcanvas-color: var(--body-color);
$offcanvas-box-shadow: $modal-content-box-shadow-xs;
$offcanvas-backdrop-bg: $backdrop-bg;
$offcanvas-backdrop-opacity: $modal-backdrop-opacity;
$offcanvas-narrow-width: 20rem;
$offcanvas-margin: 0.5rem;
$offcanvas-border-radius: $modal-content-border-radius;
