Skip to content

Latest commit

 

History

History
422 lines (324 loc) · 20.5 KB

File metadata and controls

422 lines (324 loc) · 20.5 KB
title Drawer
description 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.
toc true
css_layer components
css_media viewport
js required

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 apply margin or translate directly 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: true to render without a backdrop and without locking body scroll.
  • Built-in backdrop via ::backdrop (modal only) closes the drawer on click; set backdrop: "static" to lock clicks outside, or backdrop: false to hide it.
  • Escape key handling closes the drawer by default; set keyboard: false to disable.
  • Swipe to dismiss — drawer auto-wires a placement-aware swipe (swipe left to close drawer-start in LTR, swipe down to close drawer-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 ::backdrop fading 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-instant to skip animations.

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.

<Example class="bd-example-drawer p-0 bg-1 overflow-hidden" code={`

Drawer
Content for the drawer goes here. You can place just about any Bootstrap component or custom elements here.

`} />

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.

<Example code={` Link with href Button with data-bs-target

Drawer
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
`} />

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.

<Example code={`Enable body scrolling

Drawer with body scrolling

Try scrolling the rest of the page to see this option in action.

`} />

Body scrolling and backdrop

You can also enable <body> scrolling with a visible backdrop.

<Example code={`Enable both scrolling & backdrop

Backdrop with scrolling

Try scrolling the rest of the page to see this option in action.

`} />

Static backdrop

When backdrop is set to static, the drawer will not close when clicking outside of it.

<Example code={` Toggle static drawer

Drawer
I will not close if you click outside of me.
`} />

Instant drawer

By default, drawers animate with a slide on open and close. To disable animations, add .drawer-instant to the <dialog> element.

<Example code={` Toggle instant drawer

Instant drawer

This drawer doesn’t animate and appears instantly on open and close.

`} />

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.

<Example class="bd-example-drawer p-0 bg-1 overflow-hidden" code={`

Drawer

Place drawer content here.

`} />

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.

<Example code={` Toggle translucent drawer

Translucent drawer
Content for the translucent drawer goes here. The background blurs and saturates whatever is behind it.
`} />

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: combine it with .drawer-bottom/.drawer-top for a full-bleed panel capped by --drawer-sheet-width, or with .drawer-start/.drawer-end for a full-bleed panel capped by --drawer-sheet-height.

<Example code={` Toggle sheet drawer

Sheet drawer
Content for the sheet drawer goes here. It sits flush to the edge with no inset, border, rounded corners, or shadow.
`} />

.drawer-sheet also works with .drawer-end (or .drawer-start), pinning the panel flush against the right (or left) edge of the viewport instead:

<Example code={` Toggle sheet drawer

Sheet drawer
Content for the sheet drawer goes here. It sits flush to the edge with no inset, border, rounded corners, or shadow.
`} />

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 and ensure your close button has an explicit data-bs-target.

<Example code={`Toggle drawer

Resize your browser to show the responsive drawer toggle.

Responsive drawer

This is content within an .lg:drawer.

`} />

Placement

There’s no default placement for drawer components, so you must add one of the modifier classes below.

  • .drawer-start places drawer on the left of the viewport (shown above)
  • .drawer-end places drawer on the right of the viewport
  • .drawer-top places drawer on the top of the viewport
  • .drawer-bottom places drawer on the bottom of the viewport
  • .drawer-fullscreen covers the entire viewport

Try the top, right, bottom, and fullscreen examples out below.

<Example code={`Toggle top drawer

Drawer top
...
`} />

<Example code={`Toggle right drawer

Drawer right
...
`} />

<Example code={`Toggle bottom drawer

Drawer bottom
...
`} />

<Example code={`Toggle fullscreen drawer

Fullscreen drawer

This drawer covers the entire viewport, useful for full-page menus or modal-like experiences.

`} />

Footer

Add an optional .drawer-footer for action buttons or other content at the bottom of the drawer.

<Example class="bd-example-drawer p-0 bg-1 overflow-hidden" code={`

Drawer with footer

Content for the drawer goes here. The footer will stick to the bottom.

Close Save changes

`} />

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

Tokens for the drawer backdrop are available in a separate map as they style the native ::backdrop pseudo-element.

Usage

The drawer plugin is built on the native <dialog> element and utilizes a few classes and attributes to handle the heavy lifting:

  • .drawer on a <dialog> element enables drawer behavior
  • .drawer-start places the drawer on the left
  • .drawer-end places the drawer on the right
  • .drawer-top places the drawer on the top
  • .drawer-bottom places 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 `` 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

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](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/). 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))

Options

| 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

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 to the caller before the drawer element has actually been hidden** (i.e. before the `hidden.bs.drawer` event occurs). | | `show` | Shows a drawer element. **Returns to the caller before the drawer element has actually been shown** (i.e. before the `shown.bs.drawer` event occurs). | | `toggle` | Toggles a drawer element to shown or hidden. **Returns to the caller before the drawer element has actually been shown or hidden** (i.e. before the `shown.bs.drawer` or `hidden.bs.drawer` event occurs). |

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...
})