Drawer
Build hidden sidebars or drawers into your project for navigation, shopping carts, and more with a few classes and our JavaScript plugin. Replaces the old Offcanvas component.
How it works
Drawer builds on the native <dialog> element and our Dialog component to manage hidden sidebars via JavaScript. These sidebars, or drawers, can appear from the left, right, top, or bottom edge of the viewport. Buttons or anchors are used as triggers that are attached to specific elements you toggle, and data attributes are used to invoke our JavaScript.
- Drawer shares the same base as our Dialog component, using native
<dialog>APIs for focus trapping, backdrop, and top-layer rendering. - Use the
<dialog>element, not a<div>. Due to how CSS handles animations, don’t applymarginortranslatedirectly to.drawer— wrap it if you need those. - Modal by default, or scroll-through — the default opens the drawer modally with a backdrop; set
scroll: trueto render without a backdrop and without locking body scroll. - Built-in backdrop via
::backdrop(modal only) closes the drawer on click; setbackdrop: "static"to lock clicks outside, orbackdrop: falseto hide it. - Escape key handling closes the drawer by default; set
keyboard: falseto disable. - Swipe to dismiss — drawer auto-wires a placement-aware swipe (swipe left to close
drawer-startin LTR, swipe down to closedrawer-bottom, etc.). - Responsive placement —
.sm:drawer,.md:drawer, and up stay drawer-like below their breakpoint and collapse inline above it, making drawers useful as responsive navbars. - Only one drawer can be shown at a time (enforced by the data API).
- Animated open and close — drawer slides back out to its placement-specific off-screen position on close, with the
::backdropfading alongside it when opened modally. When authoring custom CSS, qualify your[open]rules with:not(.hiding)so the exit transition can fall through to the base state; add.drawer-instantto skip animations.
The animation effect of this component is dependent on the prefers-reduced-motion media query. See the reduced motion section of our accessibility documentation.
Examples
Drawer components
Below is a drawer example that is shown by default (via open and .show on the <dialog>). Drawer includes support for a header with a close button and an optional body class for some initial padding. We suggest that you include drawer headers with dismiss actions whenever possible, or provide an explicit dismiss action.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawer" aria-labelledby="drawerLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
Content for the drawer goes here. You can place just about any Bootstrap component or custom elements here.
</div>
</dialog>Live demo
Use the buttons below to show and hide a drawer element via JavaScript. You can use a link with the href attribute, or a button with the data-bs-target attribute. In both cases, the data-bs-toggle="drawer" is required.
<a class="btn-solid theme-primary" data-bs-toggle="drawer" href="#drawerExample" role="button" aria-controls="drawerExample">
Link with href
</a>
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerExample" aria-controls="drawerExample">
Button with data-bs-target
</button>
<dialog class="drawer drawer-start" tabindex="-1" id="drawerExample" aria-labelledby="drawerExampleLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerExampleLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<div>
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
</div>
<div class="mt-3">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu">
Menu
</button>
<div class="menu">
<a class="menu-item" href="#">Action</a>
<a class="menu-item" href="#">Another action</a>
<a class="menu-item" href="#">Something else here</a>
</div>
</div>
</div>
</dialog>Body scrolling
Scrolling the <body> element is disabled when a drawer and its backdrop are visible. Use the data-bs-scroll attribute to enable <body> scrolling.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerScrolling" aria-controls="drawerScrolling">Enable body scrolling</button>
<dialog class="drawer drawer-start" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="drawerScrolling" aria-labelledby="drawerScrollingLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerScrollingLabel">Drawer with body scrolling</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>Try scrolling the rest of the page to see this option in action.</p>
</div>
</dialog>Body scrolling and backdrop
You can also enable <body> scrolling with a visible backdrop.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerWithBothOptions" aria-controls="drawerWithBothOptions">Enable both scrolling & backdrop</button>
<dialog class="drawer drawer-start" data-bs-scroll="true" tabindex="-1" id="drawerWithBothOptions" aria-labelledby="drawerWithBothOptionsLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerWithBothOptionsLabel">Backdrop with scrolling</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>Try scrolling the rest of the page to see this option in action.</p>
</div>
</dialog>Static backdrop
When backdrop is set to static, the drawer will not close when clicking outside of it.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#staticBackdrop" aria-controls="staticBackdrop">
Toggle static drawer
</button>
<dialog class="drawer drawer-start" data-bs-backdrop="static" tabindex="-1" id="staticBackdrop" aria-labelledby="staticBackdropLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="staticBackdropLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<div>
I will not close if you click outside of me.
</div>
</div>
</dialog>Instant drawer
By default, drawers animate with a slide on open and close. To disable animations, add .drawer-instant to the <dialog> element.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#instantDrawer" aria-controls="instantDrawer">
Toggle instant drawer
</button>
<dialog class="drawer drawer-start drawer-instant" tabindex="-1" id="instantDrawer" aria-labelledby="instantDrawerLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="instantDrawerLabel">Instant drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>This drawer doesn’t animate and appears instantly on open and close.</p>
</div>
</dialog>Dark drawer
Change the appearance of drawers with utilities to better match them to different contexts like dark navbars. Here we add data-bs-theme="dark" to the .drawer, and it makes all nested elements within use dark mode.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawerDark" aria-labelledby="drawerDarkLabel" data-bs-theme="dark">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerDarkLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>Place drawer content here.</p>
</div>
</dialog>Translucent drawer
Add .drawer-translucent to the drawer panel to blur and saturate the background. This makes the panel semi-transparent so content behind it shows through.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerTranslucent" aria-controls="drawerTranslucent">
Toggle translucent drawer
</button>
<dialog class="drawer drawer-start drawer-translucent" tabindex="-1" id="drawerTranslucent" aria-labelledby="drawerTranslucentLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerTranslucentLabel">Translucent drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
Content for the translucent drawer goes here. The background blurs and saturates whatever is behind it.
</div>
</dialog>Sheet
Add .drawer-sheet to render the panel flush against the viewport edge. The sheet variant removes the drawer’s inset, border, border-radius, and box-shadow, so it sits edge-to-edge like a traditional offcanvas. It works with any placement.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerSheet" aria-controls="drawerSheet">
Toggle sheet drawer
</button>
<dialog class="drawer drawer-bottom drawer-sheet" tabindex="-1" id="drawerSheet" aria-labelledby="drawerSheetLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerSheetLabel">Sheet drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
Content for the sheet drawer goes here. It sits flush to the edge with no inset, border, rounded corners, or shadow.
</div>
</dialog>Responsive
Responsive drawer classes hide content outside the viewport from a specified breakpoint and down. Above that breakpoint, the contents within will behave as usual. For example, .lg:drawer hides content in a drawer below the lg breakpoint, but shows the content above the lg breakpoint. Responsive drawer classes are available for each breakpoint.
To make a responsive drawer, replace the .drawer base class with a responsive variant. Close buttons inside the drawer work without an explicit data-bs-target.
Resize your browser to show the responsive drawer toggle.
<button class="btn-solid theme-primary lg:d-none" type="button" data-bs-toggle="drawer" data-bs-target="#drawerResponsive" aria-controls="drawerResponsive">Toggle drawer</button>
<div class="alert theme-info d-none lg:d-block mb-3"><p>Resize your browser to show the responsive drawer toggle.</p></div>
<dialog class="lg:drawer drawer-end" tabindex="-1" id="drawerResponsive" aria-labelledby="drawerResponsiveLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerResponsiveLabel">Responsive drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p class="mb-0">This is content within an <code>.lg:drawer</code>.</p>
</div>
</dialog>Placement
There’s no default placement for drawer components, so you must add one of the modifier classes below.
.drawer-startplaces drawer on the left of the viewport (shown above).drawer-endplaces drawer on the right of the viewport.drawer-topplaces drawer on the top of the viewport.drawer-bottomplaces drawer on the bottom of the viewport.drawer-fullscreencovers the entire viewport
Try the top, right, bottom, and fullscreen examples out below.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerTop" aria-controls="drawerTop">Toggle top drawer</button>
<dialog class="drawer drawer-top" tabindex="-1" id="drawerTop" aria-labelledby="drawerTopLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerTopLabel">Drawer top</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerRight" aria-controls="drawerRight">Toggle right drawer</button>
<dialog class="drawer drawer-end" tabindex="-1" id="drawerRight" aria-labelledby="drawerRightLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerRightLabel">Drawer right</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerBottom" aria-controls="drawerBottom">Toggle bottom drawer</button>
<dialog class="drawer drawer-bottom" tabindex="-1" id="drawerBottom" aria-labelledby="drawerBottomLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerBottomLabel">Drawer bottom</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body small">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerFullscreen" aria-controls="drawerFullscreen">Toggle fullscreen drawer</button>
<dialog class="drawer drawer-fullscreen" tabindex="-1" id="drawerFullscreen" aria-labelledby="drawerFullscreenLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerFullscreenLabel">Fullscreen drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>This drawer covers the entire viewport, useful for full-page menus or modal-like experiences.</p>
</div>
</dialog>Footer
Add an optional .drawer-footer for action buttons or other content at the bottom of the drawer.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawerFooter" aria-labelledby="drawerFooterLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerFooterLabel">Drawer with footer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="none">
<path fill="currentcolor" d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4Z"/>
</svg>
</button>
</div>
<div class="drawer-body">
<p>Content for the drawer goes here. The footer will stick to the bottom.</p>
</div>
<div class="drawer-footer">
<button type="button" class="btn-solid theme-secondary" data-bs-dismiss="drawer">Close</button>
<button type="button" class="btn-solid theme-primary">Save changes</button>
</div>
</dialog>Accessibility
Since the drawer panel is built on the native <dialog> element, it inherently has the correct dialog role and modal semantics. Be sure to add aria-labelledby="..."—referencing the drawer title—to the <dialog> element.
CSS
Variables
Drawer use local CSS variables on .drawer for real-time customization. Values for the CSS variables are generated from Sass maps unique to each component and applied to the aforementioned class.
// stylelint-disable-next-line scss/dollar-variable-default
$drawer-tokens: defaults(
(
--drawer-inset: var(--spacer),
--drawer-zindex: var(--z-drawer),
--drawer-width: 400px,
--drawer-height: 30vh,
--drawer-padding-x: var(--spacer),
--drawer-padding-y: var(--spacer),
--drawer-color: var(--fg-body),
--drawer-bg: var(--bg-body),
--drawer-border-width: var(--border-width),
--drawer-border-color: var(--border-color-translucent),
--drawer-border-radius: var(--radius-7),
--drawer-box-shadow: var(--box-shadow-xl),
--drawer-transition-duration: .3s,
--drawer-transition-timing: var(--transition-timing-overlay),
--drawer-title-line-height: 1.5,
--drawer-backdrop-bg: color-mix(in oklch, var(--bg-body) 25%, transparent),
--drawer-backdrop-blur: 8px,
),
$drawer-tokens
);
Tokens for the drawer backdrop are available in a separate map as they style the native ::backdrop pseudo-element.
// stylelint-disable-next-line scss/dollar-variable-default
$drawer-backdrop-tokens: defaults(
(
--drawer-backdrop-bg: var(--bg-body),
--drawer-backdrop-opacity: 25%,
--drawer-backdrop-blur: 8px,
),
$drawer-backdrop-tokens
);
Usage
The drawer plugin is built on the native <dialog> element and utilizes a few classes and attributes to handle the heavy lifting:
.draweron a<dialog>element enables drawer behavior.drawer-startplaces the drawer on the left.drawer-endplaces the drawer on the right.drawer-topplaces the drawer on the top.drawer-bottomplaces the drawer on the bottom
Add a dismiss button with the data-bs-dismiss="drawer" attribute, which triggers the JavaScript functionality. Be sure to use the <button> element with it for proper behavior across all devices.
Via data attributes
| Attribute | Description |
|---|---|
data-bs-toggle="drawer" | Initializes drawer behavior on the trigger element. |
data-bs-target | CSS selector for the <dialog> drawer element to open (or use href on a link). |
data-bs-dismiss="drawer" | On a dismiss control, closes the drawer when activated. |
Toggle
Add data-bs-toggle="drawer" and a data-bs-target or href to the element to automatically assign control of one drawer element. The data-bs-target attribute accepts a CSS selector to apply the drawer to. Be sure to use a <dialog> element with the class drawer.
Dismiss
Dismissal can be achieved with the data-bs-dismiss attribute on a button within the drawer as demonstrated below:
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close"></button>or on a button outside the drawer using the additional data-bs-target as demonstrated below:
<button type="button" class="btn-close" data-bs-dismiss="drawer" data-bs-target="#my-drawer" aria-label="Close"></button>While both ways to dismiss a drawer are supported, keep in mind that dismissing from outside a drawer does not match the ARIA Authoring Practices Guide dialog (modal) pattern. Do this at your own risk.
Via JavaScript
Enable manually with:
const drawerElementList = document.querySelectorAll('dialog.drawer')
const drawerList = [...drawerElementList].map(drawerEl => new bootstrap.Drawer(drawerEl))Dependencies
The drawer plugin requires the following JavaScript files if you’re building Bootstrap’s JS from source:
| File | Description |
|---|---|
js/src/drawer.ts | Main drawer component |
js/src/base-component.ts | Base component class |
js/src/dialog-base.ts | Base dialog component |
js/src/dom/data.ts | Element data store |
js/src/dom/event-handler.ts | Event handling utilities |
js/src/dom/manipulator.ts | Data attribute manipulation |
js/src/dom/selector-engine.ts | DOM selector utilities |
js/src/util/component-functions.ts | Shared component helpers |
js/src/util/config.ts | Configuration base class |
js/src/util/index.ts | Core utility functions |
js/src/util/swipe.ts | Swipe gesture utilities |
Options
As options can be passed via data attributes or JavaScript, you can append an option name to data-bs-, as in data-bs-animation="{value}". Make sure to change the case type of the option name from “camelCase” to “kebab-case” when passing the options via data attributes. For example, use data-bs-custom-class="beautifier" instead of data-bs-customClass="beautifier".
All components support a reserved data attribute data-bs-config that can house simple component configuration as a JSON string. When an element has data-bs-config='{"delay":0, "title":123}' and data-bs-title="456" attributes, the final title value will be 456 and the separate data attributes will override values given on data-bs-config. In addition, existing data attributes are able to house JSON values like data-bs-delay='{"show":0,"hide":150}'.
The final configuration object is the merged result of data-bs-config, data-bs-, and js object where the latest given key-value overrides the others.
| Name | Type | Default | Description |
|---|---|---|---|
backdrop | boolean or the string static | true | Apply a backdrop on body while drawer is open. Alternatively, specify static for a backdrop which doesn’t close the drawer when clicked. |
keyboard | boolean | true | Closes the drawer when escape key is pressed. |
scroll | boolean | false | Allow body scrolling while drawer is open. |
Methods
Methods that show or hide a component return a promise. The promise resolves when the transition ends, so await continues at the same moment a shown.bs.* or hidden.bs.* listener runs. The methods still return immediately and never block the caller. A call on a component that is already transitioning does nothing and resolves right away. Learn more in our JavaScript docs.
Activates your content as a drawer element. Accepts an optional options object.
You can create a drawer instance with the constructor, for example:
const bsDrawer = new bootstrap.Drawer('#myDrawer')| Method | Description |
|---|---|
dispose | Destroys an element’s drawer. |
getInstance | Static method which allows you to get the drawer instance associated with a DOM element. |
getOrCreateInstance | Static method which allows you to get the drawer instance associated with a DOM element, or create a new one in case it wasn’t initialized. |
hide | Hides a drawer element. Returns a promise that resolves once the drawer element is hidden (i.e. after the hidden.bs.drawer event fires). |
show | Shows a drawer element. Returns a promise that resolves once the drawer element is shown (i.e. after the shown.bs.drawer event fires). |
toggle | Toggles a drawer element to shown or hidden. Returns a promise that resolves once the drawer element is shown or hidden (i.e. after the shown.bs.drawer or hidden.bs.drawer event fires). |
Events
Bootstrap’s drawer class exposes a few events for hooking into drawer functionality.
| Event type | Description |
|---|---|
hide.bs.drawer | This event is fired immediately when the hide method has been called. |
hidden.bs.drawer | This event is fired when a drawer element has been hidden from the user (will wait for CSS transitions to complete). |
hidePrevented.bs.drawer | This event is fired when the drawer is shown, its backdrop is static and a click outside of the drawer is performed. The event is also fired when the escape key is pressed and the keyboard option is set to false. |
show.bs.drawer | This event fires immediately when the show instance method is called. |
shown.bs.drawer | This event is fired when a drawer element has been made visible to the user (will wait for CSS transitions to complete). |
const myDrawer = document.getElementById('myDrawer')
myDrawer.addEventListener('hidden.bs.drawer', event => {
// do something...
})