Drawer
A panel that slides in from an edge of the screen, built on the native dialog element. Bootstrap 6’s replacement for offcanvas.
Bootstrap’s drawer docs describe the markup and CSS.
Example
Open a drawer with bsDrawerToggle, which also keeps aria-expanded and aria-controls in sync. bsDrawerClose closes the drawer it is in. Modal drawers trap focus, close on Escape and on backdrop clicks, and stop the page from scrolling.
<button type="button" bsButton theme="primary" [bsDrawerToggle]="basicDrawer">Open drawer</button>
<dialog bsDrawer #basicDrawer="bsDrawer" aria-labelledby="basicDrawer-title">
<div class="drawer-header">
<h2 class="drawer-title h5" id="basicDrawer-title">Drawer</h2>
<button type="button" bsCloseButton bsDrawerClose></button>
</div>
<div class="drawer-body">
<p>
Some text as placeholder. In real life you can have the elements you have chosen, like text,
images and lists.
</p>
</div>
</dialog>Placement
Set placement to start (the default), end, top, bottom or fullscreen. start and end follow the text direction.
<div class="hstack gap-2 flex-wrap">
@for (p of placements; track p) {
<button
type="button"
bsButton="outline"
theme="primary"
(click)="placement.set(p); drawer.show()">
{{ p }}
</button>
}
</div>
<dialog
bsDrawer
#drawer="bsDrawer"
[placement]="placement()"
aria-labelledby="placement-drawer-title">
<div class="drawer-header">
<h2 class="drawer-title h5" id="placement-drawer-title">Placement: {{ placement() }}</h2>
<button type="button" bsCloseButton bsDrawerClose></button>
</div>
<div class="drawer-body">
<p>This drawer slides in from the {{ placement() }} edge.</p>
</div>
</dialog>Body scrolling
Set scroll with [backdrop]="false" to keep the page scrollable and interactive. The drawer then opens without a backdrop and does not trap focus. With a backdrop, the drawer stays modal but the page still scrolls.
<button type="button" bsButton theme="primary" [bsDrawerToggle]="scrollDrawer">
Enable body scrolling
</button>
<dialog
bsDrawer
#scrollDrawer="bsDrawer"
scroll
[backdrop]="false"
aria-labelledby="scrollDrawer-title">
<div class="drawer-header">
<h2 class="drawer-title h5" id="scrollDrawer-title">Drawer with body scrolling</h2>
<button type="button" bsCloseButton bsDrawerClose></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
With backdrop="static" the drawer does not close on backdrop clicks. Add [keyboard]="false" to ignore Escape as well.
<button type="button" bsButton theme="primary" [bsDrawerToggle]="staticDrawer">
Toggle static drawer
</button>
<dialog bsDrawer #staticDrawer="bsDrawer" backdrop="static" aria-labelledby="staticDrawer-title">
<div class="drawer-header">
<h2 class="drawer-title h5" id="staticDrawer-title">Drawer</h2>
<button type="button" bsCloseButton bsDrawerClose></button>
</div>
<div class="drawer-body">
<p>I will not close if you click outside of me.</p>
</div>
</dialog>Responsive
Set responsive to a breakpoint to use Bootstrap’s .lg:drawer style classes: the content is a drawer below the breakpoint and shows inline from it up. An open drawer closes when the viewport grows past the breakpoint.
<button
type="button"
bsButton
theme="primary"
class="lg:d-none"
[bsDrawerToggle]="responsiveDrawer">
Toggle drawer
</button>
<dialog
bsDrawer
#responsiveDrawer="bsDrawer"
placement="end"
responsive="lg"
aria-labelledby="responsiveDrawer-title">
<div class="drawer-header">
<h2 class="drawer-title h5" id="responsiveDrawer-title">Responsive drawer</h2>
<button type="button" bsCloseButton bsDrawerClose></button>
</div>
<div class="drawer-body">
<p class="mb-0">
This is content within an <code>.lg:drawer</code>. Resize your browser to see it switch
between inline and drawer.
</p>
</div>
</dialog>Opening from code
Call openDrawer() on BsDialogService with a component or template to show a drawer without writing the <dialog> yourself. A template gets the ref as its context, so it can close() with a value, and the ref’s result promise resolves with it. See opening a dialog from code for the options.
Size: Medium
<button type="button" bsButton theme="primary" (click)="choose()">Choose a size</button>
<p class="mt-3 mb-0">Size: {{ size() }}</p>
<ng-template #picker let-drawer>
<div class="drawer-header">
<h5 class="drawer-title">Size</h5>
<button type="button" bsCloseButton bsDrawerClose></button>
</div>
<div class="drawer-body">
<div bsListGroup>
@for (option of sizes; track option) {
<button
type="button"
bsListGroupItem
[active]="option === size()"
(click)="drawer.close(option)">
{{ option }}
</button>
}
</div>
</div>
</ng-template>API
BsDrawer
Selector: dialog[bsDrawer] · Exported as: bsDrawer
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
placement | 'start' | 'end' | 'top' | 'bottom' | 'fullscreen' | 'start' | Edge the drawer slides in from. |
responsive | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | null | null | Shows the content inline from this breakpoint up. |
scroll | boolean | false | Keeps the page scrollable while the drawer is open. |
open | boolean | false | Whether the drawer is open. Supports [(open)]. |
backdrop | boolean | 'static' | true | Shows a backdrop. static keeps the drawer open on backdrop clicks. |
keyboard | boolean | true | Closes the drawer on Escape. |
animation | boolean | true | Slides the drawer in and out. |
id | string | generated | Element id, used by toggles for aria-controls. |
Outputs
| Name | Type | Description |
|---|---|---|
openChange | boolean | Emits when the drawer opens or closes from inside. |
shown | void | Emits after the drawer is shown. |
hidden | void | Emits after the drawer is hidden. |
dismissed | 'escape' | 'backdrop' | Emits when the user dismisses the drawer. |
Methods
| Name | Type | Description |
|---|---|---|
show() | void | Opens the drawer. |
hide() | void | Closes the drawer. |
toggle() | void | Toggles the drawer. |
isOpen | Signal<boolean> | Current open state. |
BsDrawerToggle
Selector: [bsDrawerToggle]
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
bsDrawerToggle | BsDrawer | required | The drawer to open and close. |
BsDialogClose
Selector: [bsDrawerClose], [bsDialogClose]