Files
tabler/docs/content/ui/components/offcanvas.mdx

102 lines
8.9 KiB
Plaintext

---
title: Offcanvas
summary: An offcanvas is a hidden panel that slides in from the edge of the screen, for navigation, filters or settings.
description: Sidebar panel that slides in from the edge of the viewport.
related: [/ui/components/modal]
source: core/scss/ui/_offcanvas.scss
classnames:
component:
- class: offcanvas
desc: Container element, hidden until Bootstrap opens it
part:
- class: offcanvas-header
desc: Title bar with a bottom border
- class: offcanvas-title
desc: Heading inside the header
- class: offcanvas-body
desc: Content area
- class: offcanvas-footer
desc: Row of actions at the bottom
modifier:
- class: offcanvas-narrow
desc: Narrower panel, 20rem instead of the default width
- class: offcanvas-floating
desc: Keeps a 0.5rem gap between the panel and the viewport edges
direction:
- class: offcanvas-start
desc: Slides in from the leading edge
- class: offcanvas-end
desc: Slides in from the trailing edge
- class: offcanvas-top
desc: Slides in from the top
- class: offcanvas-bottom
desc: Slides in from the bottom
size:
- class: offcanvas-{breakpoint}
desc: Behaves as an offcanvas below the breakpoint and as normal content above it
---
import Example from '@components/Example.astro';
import CodeDocs from '@components/CodeDocs.astro';
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.
<Example raw code={`<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>`}>
<div class="offcanvas offcanvas-start show position-static" 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>
</Example>
## 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.
<Example raw code={`<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>`}>
<div class="offcanvas offcanvas-end show position-static" 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>
</Example>
## 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.
<Example raw code={`<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>`}>
<div class="offcanvas offcanvas-end offcanvas-narrow show position-static" 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>
</Example>
## 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.
<Example raw code={`<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>`}>
<div class="offcanvas offcanvas-end offcanvas-floating show position-static" 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>
</Example>
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"`](/ui/layout/page-layouts#floating-offcanvas) 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.
<Example raw code={`<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>`}>
<div class="offcanvas offcanvas-bottom h-auto show position-static" 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>
</Example>
## Accessibility
- Point `aria-labelledby` at 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-controls` with the panel id. Bootstrap manages `aria-expanded` itself.
- <kbd>Escape</kbd> 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.
## SCSS variables
Use these SCSS variables to customize the offcanvas component. The default values are:
<CodeDocs name="offcanvas-variables" file="core/scss/_variables.scss" />