# Drawer A panel that slides from an edge and can be dragged away, with snap points and a scaled background. ```ehtml Example import { Drawer, DrawerBody, DrawerFooter, DrawerClose } from "@elements/ui/drawer"; import { Button } from "@elements/ui/button"; Open drawer ... submit(goal)}>Submit Cancel ... ``` ## Parts | Part | What it is | |---|---| | `Drawer` | The root: owns open and snapPoint, renders the trigger slot and, while open, the `` overlay, backdrop, handle and panel. | | `DrawerHeader` | Stacks a title and description; centered on bottom and top drawers below 48rem. | | `DrawerTitle` | An ``; names the drawer (aria-labelledby). | | `DrawerDescription` | A ``; describes the drawer (aria-describedby). | | `DrawerBody` | The content between header and footer; scrolls when tall, and is then a Tab stop so the keyboard can scroll it. Dragging starts only once it is scrolled to the top. | | `DrawerFooter` | Actions pinned to the bottom, stacked full width. | | `DrawerClose` | Wraps any element; clicking it closes this drawer. | | `DrawerWrapper` | Wrap the page in it; a drawer with scaleBackground scales it back while open and as it is dragged. | ## Attributes ### Drawer | Attribute | Type | Default | Description | |---|---|---|---| | `open` | `boolean` (two-way) | `false` | Whether the drawer is open. Bind it to control it; the drawer writes false back when it closes itself. Omit it and the trigger slot opens it. | | `direction` | `"bottom" \| "top" \| "left" \| "right"` | `"bottom"` | The edge the drawer slides from and is dragged back to. | | `title` | `string` | `""` | Renders a DrawerTitle in a header and names the drawer. | | `description` | `string` | `""` | Renders a DrawerDescription under the title. | | `label` | `string` | `""` | aria-label for a drawer with no visible title. | | `modal` | `boolean \| "trap-focus"` | `true` | true: backdrop, inert page, focus trap, scroll lock. "trap-focus": focus is trapped, but there is no backdrop or lock and the page takes clicks. false: the page stays usable (combine with snap points for a map-style sheet). | | `dismissible` | `boolean` | `true` | false: dragging, Escape and a press outside never close it. Close it from your own control. | | `dismissOnOutside` | `boolean` | `true` | A press outside closes it. | | `handle` | `boolean` | `true` | Shows the grab handle at the inner edge. | | `handleOnly` | `boolean` | `false` | Only the handle starts a drag; the content scrolls and selects freely. | | `handleCycles` | `boolean` | `true` | A click on the handle moves to the next snap point, and from the last closes. false turns that off. | | `closeButton` | `boolean` | `false` | Shows an X button in the corner. | | `snapPoints` | `(number \| string)[]` | `[]` | Heights the drawer rests at, smallest first: fractions of the viewport (0.5), px (320 or "320px") or rem ("20rem"). | | `snapPoint` | `number \| string \| null` (two-way) | `null` | The active snap point; null starts at the first. Two-way: the drawer writes the point it settles on, and goes back to the first point once a close finishes, so every open starts there. | | `fadeFromIndex` | `number` | `-1` | The snap point index at which the backdrop is fully shown; it fades in from the point before. -1 is the last. | | `snapToSequentialPoints` | `boolean` | `false` | A fast fling moves one snap point at a time instead of skipping to the first or last. | | `closeThreshold` | `number` | `0.25` | Fraction of the drawer's size a slow drag must pass to close it on release. | | `swipeArea` | `boolean` | `false` | Renders an invisible strip on the drawer's edge. A swipe from it opens the drawer, which follows the finger; let go past half its size or with a flick and it stays open, otherwise it closes again. | | `swipeAreaDirection` | `"up" \| "down" \| "left" \| "right" \| ""` | `""` | The swipe that opens the drawer from the swipe area. The strip sits on the edge that swipe starts from. Empty: toward the middle from the drawer's own edge. | | `fixed` | `boolean` | `false` | With repositionInputs and the on-screen keyboard up, the panel keeps its top where it is and ends at the keyboard instead of moving up, when there is room above it. | | `noBodyStyles` | `boolean` | `false` | A modal drawer sets no scroll lock styles on the page; it is otherwise modal. | | `swipeAreaDisabled` | `boolean` | `false` | Keeps the swipe area rendered, marked data-disabled, but a swipe from it opens nothing and the page under it takes touches. | | `repositionInputs` | `boolean` | `true` | Keeps a bottom drawer above the on-screen keyboard while a text field inside has focus. Off, the browser handles it. | | `scrollLockTimeout` | `number` | `100` | ms after scrolling content inside during which a drag does not start. | | `scaleBackground` | `boolean` | `false` | Scales every DrawerWrapper back while open, following the drag. | | `initialFocus` | `DialogFocus` | `""` | CSS selector of the element to focus on open, or a function of the interaction type (keyboard, mouse, touch, pen) that returns an element, a selector, true for the default or false to leave focus. Default: [autofocus], else the first focusable element that is not a link, else the panel. | | `returnFocus` | `boolean` | `true` | Return focus to the trigger (or whatever had focus) when it closes. | | `finalFocus` | `DialogFocus` | `""` | CSS selector of the element to focus on close, in place of the trigger, or a function of the interaction type that returns an element, a selector, true for the trigger or false to leave focus. | | `class` | `string` | `""` | Extra classes on the panel. | | `onOpenChange` | `(open: boolean, reason?: DrawerChangeReason, details?: DrawerChangeDetails) => void` | `() => {}` | Called when the drawer opens or closes itself, with the reason: trigger-press, outside-press, escape-key, close-press, swipe (a drag, or the swipe area), close-watcher (a platform close request such as Android's back gesture), focus-out or none. The third argument is the change details: { reason, event (the DOM event behind the change, or null), trigger (the trigger element on trigger-press) }. | | `onSnapPointChange` | `(point: number \| string, reason?: DrawerChangeReason) => void` | `() => {}` | Called when a drag or the handle settles on a different snap point, with the reason: swipe for a drag, trigger-press for a handle click, none for the return to the first point after a close. | | `onDrag` | `(e: PointerEvent \| null, progress: number) => void` | `() => {}` | Called on every drag move; progress is 0 (open) to 1 (at the closed edge). | | `onRelease` | `(e: PointerEvent \| null, open: boolean) => void` | `() => {}` | Called when a drag ends; open is whether the drawer stays open. | | `onOpenChangeComplete` | `(open: boolean) => void` | `() => {}` | Called after the enter animation (true) or once the drawer has left the page after its exit (false). | | `onEscapeKeyDown` | `(e: KeyboardEvent) => void` | `() => {}` | Called on Escape before closing; e.preventDefault() keeps it open, and e.allowPropagation() lets the Escape reach the page's own key handlers too. | | `onPointerDownOutside` | `(e: PointerEvent) => void` | `() => {}` | Called on a press outside before closing; e.preventDefault() keeps it open. | | `onInteractOutside` | `(e: Event) => void` | `() => {}` | Called before a press or focus outside dismisses it; e.preventDefault() keeps it open. | | `onOpenAutoFocus` | `(e: Event) => void` | `() => {}` | Called before focus moves in on open; e.preventDefault() leaves focus to the handler. | | `onCloseAutoFocus` | `(e: Event) => void` | `() => {}` | Called before focus returns on close; e.preventDefault() leaves focus to the handler. | ### DrawerHeader, DrawerTitle, DrawerDescription, DrawerBody, DrawerFooter, DrawerWrapper | Attribute | Type | Default | Description | |---|---|---|---| | `class` | `string` | `""` | Extra classes. | ## Slots | Slot | Content | |---|---| | `trigger` | The element that opens the drawer. It gets aria-haspopup, aria-expanded, aria-controls and data-state. | | `default` | The drawer's content, below the handle and header. | ## Keyboard | Keys | Action | |---|---| | `Space / Enter` | On the trigger: opens the drawer. | | `Tab` | Moves to the next focusable element inside; wraps from the last to the first. | | `Shift + Tab` | Moves to the previous focusable element; wraps. | | `Enter / Space` | On the handle (with snap points): the next snap point, and from the last a close, as a click does. | | `Arrow toward open / toward the edge` | On the handle: one snap point up or down (ArrowUp and ArrowDown on a bottom drawer); never closes. | | `Home / End` | On the handle: the first or last snap point. | | `PageUp / PageDown, arrows, Space` | On a DrawerBody that scrolls (a Tab stop while it overflows): scroll it. | | `Escape` | Closes the drawer (unless dismissible is false or onEscapeKeyDown prevents it). With a drag in progress, cancels the drag. | ## Data attributes | Attribute | Values | On | Description | |---|---|---|---| | `data-open` | present | .dialog-overlay, .drawer-backdrop, .drawer | While open; the same moment as data-state="open". | | `data-closed, data-ending-style` | present | .dialog-overlay, .drawer-backdrop, .drawer | During the exit animation; the same moment as data-state="closed". | | `data-starting-style` | present | .dialog-overlay, .drawer-backdrop, .drawer | For the first frame after the overlay mounts, so a CSS transition can start from it. | | `data-popup-open` | present | trigger | While open; the same moment as the trigger's data-state="open". | | `data-state` | `"open" \| "closed"` | trigger, .dialog-overlay, .drawer-backdrop, .drawer | closed during the exit animation. | | `data-direction` | `"bottom" \| "top" \| "left" \| "right"` | .drawer | | | `data-swipe-direction` | `"down" \| "up" \| "left" \| "right"` | .drawer | The edge the drawer sits on. | | `data-swipe-axis` | `"x" \| "y"` | .drawer | | | `data-swiping` | present | .drawer, .drawer-backdrop, .drawer-wrapper | While a drag is moving the drawer. | | `data-snap-points` | present | .drawer | The drawer has snap points. | | `data-drawer-scroll-stop` | present | .drawer-body | The body overflows and is a Tab stop (tabindex 0), a region named after the title. | | `data-expanded` | present | .drawer | At the last (largest) snap point. | | `data-keyboard` | present | .drawer | Lifted above the on-screen keyboard (repositionInputs); --drawer-keyboard holds the covered height. | | `data-nested-drawer-open` | present | .drawer | A drawer opened from inside this one is open; this one steps back. | | `data-active` | present | .drawer-wrapper | Scaled back by a scaleBackground drawer. | | `data-drawer-no-drag` | set by you | any element inside | A press here never starts a drag. Set it to x or y to block only that axis. | | `--drawer-x, --drawer-y` | px | .drawer | The panel's offset from its resting place, while dragging and for snap points. | | `--drawer-progress` | 0 to 1 | .drawer, .drawer-wrapper | 1 open, 0 closed; follows the drag. | | `--nested-drawers` | count | .drawer | Drawers open inside this one. | | `data-nested-drawer-swiping` | present | .drawer | A drawer opened from inside this one is being dragged; this one follows it forward (--drawer-nested-progress, 1 to 0). | | `--drawer-frontmost-height` | px | .drawer | The height of the drawer open inside this one. | | `data-nested` | present | .drawer-overlay | This drawer was opened from inside another. | | `data-swipe-dismiss` | present | .drawer | A swipe closed it; set through the exit animation. | | `--drawer-swipe-strength` | 0.1 to 1 | .drawer | Set when a swipe closes it: a faster fling gives a smaller value and a shorter exit. | | `--drawer-swipe-movement-x, --drawer-swipe-movement-y` | px | .drawer | How far a drag has moved the panel from where it rests. | | `--drawer-swipe-progress` | 0 to 1 | .drawer, .drawer-backdrop | 0 at rest, 1 at the closed edge. | | `--drawer-height` | px | .drawer | The panel's height. | | `--drawer-snap-point-offset` | px | .drawer | How far the active snap point leaves the panel translated toward its edge. | | `--drawer-inset` | length | .drawer (set by the caller) | Floats the panel that far off the viewport edges, with every corner rounded. 0 by default. | | `--drawer-overlay-min-opacity` | 0 to 1 | .drawer or .drawer-backdrop (set by the caller) | A floor for the backdrop's opacity, at every snap point and during a drag. Unset, 0.5 with snap points and 0 without. | | `data-swipe-opened` | present | .drawer, .drawer-backdrop | While a drawer the swipe area opened is open: it entered with the finger, not its enter animation. | | `data-disabled` | present | .drawer-swipe-area | swipeAreaDisabled is set. | | `data-slot` | `"drawer-overlay" \| "drawer-content"` | .drawer-backdrop, .drawer | The part's name. | | `data-fixed` | present | .drawer | fixed is keeping the panel's top in place above the keyboard; --drawer-fixed-top holds it. | | `data-swiping` | present | .drawer-swipe-area | While a swipe on the swipe area runs. | | `data-swipe-direction` | `"up" \| "down" \| "left" \| "right"` | .drawer-swipe-area | The swipe that opens the drawer. | | `--drawer-bleed-background` | color | .drawer | Set it to change the fill past the panel's edge, shown when a drag lifts the panel past fully open. Defaults to the panel background. | ## Accessibility - The overlay is a native `` opened with showModal(): role dialog, the top layer, and an inert page behind it. - aria-modal="true", aria-labelledby (the title) and aria-describedby (the description) are set on it. - Focus moves in on open, is trapped while modal and returns to the trigger on close. - Dragging is a pointer convenience: Escape, a press outside, DrawerClose and the optional close button do the same from the keyboard. Without snap points the handle is decorative (aria-hidden). With them it is a button named for what Enter does (Expand drawer, Close drawer), in the Tab order, and the arrows, Home and End move between snap points. - A drawer resting at a low snap point never focuses a control below the viewport: focus goes to the first control it shows, or the panel. ## See also - [Button](button): A button or a link that looks like one, in six variants and four sizes. - [AlertDialog](alert-dialog): A modal that interrupts with something important and waits for an answer. - [Sheet](sheet): A dialog that slides in from an edge of the screen, for content that complements the page.
`; describes the drawer (aria-describedby). | | `DrawerBody` | The content between header and footer; scrolls when tall, and is then a Tab stop so the keyboard can scroll it. Dragging starts only once it is scrolled to the top. | | `DrawerFooter` | Actions pinned to the bottom, stacked full width. | | `DrawerClose` | Wraps any element; clicking it closes this drawer. | | `DrawerWrapper` | Wrap the page in it; a drawer with scaleBackground scales it back while open and as it is dragged. | ## Attributes ### Drawer | Attribute | Type | Default | Description | |---|---|---|---| | `open` | `boolean` (two-way) | `false` | Whether the drawer is open. Bind it to control it; the drawer writes false back when it closes itself. Omit it and the trigger slot opens it. | | `direction` | `"bottom" \| "top" \| "left" \| "right"` | `"bottom"` | The edge the drawer slides from and is dragged back to. | | `title` | `string` | `""` | Renders a DrawerTitle in a header and names the drawer. | | `description` | `string` | `""` | Renders a DrawerDescription under the title. | | `label` | `string` | `""` | aria-label for a drawer with no visible title. | | `modal` | `boolean \| "trap-focus"` | `true` | true: backdrop, inert page, focus trap, scroll lock. "trap-focus": focus is trapped, but there is no backdrop or lock and the page takes clicks. false: the page stays usable (combine with snap points for a map-style sheet). | | `dismissible` | `boolean` | `true` | false: dragging, Escape and a press outside never close it. Close it from your own control. | | `dismissOnOutside` | `boolean` | `true` | A press outside closes it. | | `handle` | `boolean` | `true` | Shows the grab handle at the inner edge. | | `handleOnly` | `boolean` | `false` | Only the handle starts a drag; the content scrolls and selects freely. | | `handleCycles` | `boolean` | `true` | A click on the handle moves to the next snap point, and from the last closes. false turns that off. | | `closeButton` | `boolean` | `false` | Shows an X button in the corner. | | `snapPoints` | `(number \| string)[]` | `[]` | Heights the drawer rests at, smallest first: fractions of the viewport (0.5), px (320 or "320px") or rem ("20rem"). | | `snapPoint` | `number \| string \| null` (two-way) | `null` | The active snap point; null starts at the first. Two-way: the drawer writes the point it settles on, and goes back to the first point once a close finishes, so every open starts there. | | `fadeFromIndex` | `number` | `-1` | The snap point index at which the backdrop is fully shown; it fades in from the point before. -1 is the last. | | `snapToSequentialPoints` | `boolean` | `false` | A fast fling moves one snap point at a time instead of skipping to the first or last. | | `closeThreshold` | `number` | `0.25` | Fraction of the drawer's size a slow drag must pass to close it on release. | | `swipeArea` | `boolean` | `false` | Renders an invisible strip on the drawer's edge. A swipe from it opens the drawer, which follows the finger; let go past half its size or with a flick and it stays open, otherwise it closes again. | | `swipeAreaDirection` | `"up" \| "down" \| "left" \| "right" \| ""` | `""` | The swipe that opens the drawer from the swipe area. The strip sits on the edge that swipe starts from. Empty: toward the middle from the drawer's own edge. | | `fixed` | `boolean` | `false` | With repositionInputs and the on-screen keyboard up, the panel keeps its top where it is and ends at the keyboard instead of moving up, when there is room above it. | | `noBodyStyles` | `boolean` | `false` | A modal drawer sets no scroll lock styles on the page; it is otherwise modal. | | `swipeAreaDisabled` | `boolean` | `false` | Keeps the swipe area rendered, marked data-disabled, but a swipe from it opens nothing and the page under it takes touches. | | `repositionInputs` | `boolean` | `true` | Keeps a bottom drawer above the on-screen keyboard while a text field inside has focus. Off, the browser handles it. | | `scrollLockTimeout` | `number` | `100` | ms after scrolling content inside during which a drag does not start. | | `scaleBackground` | `boolean` | `false` | Scales every DrawerWrapper back while open, following the drag. | | `initialFocus` | `DialogFocus` | `""` | CSS selector of the element to focus on open, or a function of the interaction type (keyboard, mouse, touch, pen) that returns an element, a selector, true for the default or false to leave focus. Default: [autofocus], else the first focusable element that is not a link, else the panel. | | `returnFocus` | `boolean` | `true` | Return focus to the trigger (or whatever had focus) when it closes. | | `finalFocus` | `DialogFocus` | `""` | CSS selector of the element to focus on close, in place of the trigger, or a function of the interaction type that returns an element, a selector, true for the trigger or false to leave focus. | | `class` | `string` | `""` | Extra classes on the panel. | | `onOpenChange` | `(open: boolean, reason?: DrawerChangeReason, details?: DrawerChangeDetails) => void` | `() => {}` | Called when the drawer opens or closes itself, with the reason: trigger-press, outside-press, escape-key, close-press, swipe (a drag, or the swipe area), close-watcher (a platform close request such as Android's back gesture), focus-out or none. The third argument is the change details: { reason, event (the DOM event behind the change, or null), trigger (the trigger element on trigger-press) }. | | `onSnapPointChange` | `(point: number \| string, reason?: DrawerChangeReason) => void` | `() => {}` | Called when a drag or the handle settles on a different snap point, with the reason: swipe for a drag, trigger-press for a handle click, none for the return to the first point after a close. | | `onDrag` | `(e: PointerEvent \| null, progress: number) => void` | `() => {}` | Called on every drag move; progress is 0 (open) to 1 (at the closed edge). | | `onRelease` | `(e: PointerEvent \| null, open: boolean) => void` | `() => {}` | Called when a drag ends; open is whether the drawer stays open. | | `onOpenChangeComplete` | `(open: boolean) => void` | `() => {}` | Called after the enter animation (true) or once the drawer has left the page after its exit (false). | | `onEscapeKeyDown` | `(e: KeyboardEvent) => void` | `() => {}` | Called on Escape before closing; e.preventDefault() keeps it open, and e.allowPropagation() lets the Escape reach the page's own key handlers too. | | `onPointerDownOutside` | `(e: PointerEvent) => void` | `() => {}` | Called on a press outside before closing; e.preventDefault() keeps it open. | | `onInteractOutside` | `(e: Event) => void` | `() => {}` | Called before a press or focus outside dismisses it; e.preventDefault() keeps it open. | | `onOpenAutoFocus` | `(e: Event) => void` | `() => {}` | Called before focus moves in on open; e.preventDefault() leaves focus to the handler. | | `onCloseAutoFocus` | `(e: Event) => void` | `() => {}` | Called before focus returns on close; e.preventDefault() leaves focus to the handler. | ### DrawerHeader, DrawerTitle, DrawerDescription, DrawerBody, DrawerFooter, DrawerWrapper | Attribute | Type | Default | Description | |---|---|---|---| | `class` | `string` | `""` | Extra classes. | ## Slots | Slot | Content | |---|---| | `trigger` | The element that opens the drawer. It gets aria-haspopup, aria-expanded, aria-controls and data-state. | | `default` | The drawer's content, below the handle and header. | ## Keyboard | Keys | Action | |---|---| | `Space / Enter` | On the trigger: opens the drawer. | | `Tab` | Moves to the next focusable element inside; wraps from the last to the first. | | `Shift + Tab` | Moves to the previous focusable element; wraps. | | `Enter / Space` | On the handle (with snap points): the next snap point, and from the last a close, as a click does. | | `Arrow toward open / toward the edge` | On the handle: one snap point up or down (ArrowUp and ArrowDown on a bottom drawer); never closes. | | `Home / End` | On the handle: the first or last snap point. | | `PageUp / PageDown, arrows, Space` | On a DrawerBody that scrolls (a Tab stop while it overflows): scroll it. | | `Escape` | Closes the drawer (unless dismissible is false or onEscapeKeyDown prevents it). With a drag in progress, cancels the drag. | ## Data attributes | Attribute | Values | On | Description | |---|---|---|---| | `data-open` | present | .dialog-overlay, .drawer-backdrop, .drawer | While open; the same moment as data-state="open". | | `data-closed, data-ending-style` | present | .dialog-overlay, .drawer-backdrop, .drawer | During the exit animation; the same moment as data-state="closed". | | `data-starting-style` | present | .dialog-overlay, .drawer-backdrop, .drawer | For the first frame after the overlay mounts, so a CSS transition can start from it. | | `data-popup-open` | present | trigger | While open; the same moment as the trigger's data-state="open". | | `data-state` | `"open" \| "closed"` | trigger, .dialog-overlay, .drawer-backdrop, .drawer | closed during the exit animation. | | `data-direction` | `"bottom" \| "top" \| "left" \| "right"` | .drawer | | | `data-swipe-direction` | `"down" \| "up" \| "left" \| "right"` | .drawer | The edge the drawer sits on. | | `data-swipe-axis` | `"x" \| "y"` | .drawer | | | `data-swiping` | present | .drawer, .drawer-backdrop, .drawer-wrapper | While a drag is moving the drawer. | | `data-snap-points` | present | .drawer | The drawer has snap points. | | `data-drawer-scroll-stop` | present | .drawer-body | The body overflows and is a Tab stop (tabindex 0), a region named after the title. | | `data-expanded` | present | .drawer | At the last (largest) snap point. | | `data-keyboard` | present | .drawer | Lifted above the on-screen keyboard (repositionInputs); --drawer-keyboard holds the covered height. | | `data-nested-drawer-open` | present | .drawer | A drawer opened from inside this one is open; this one steps back. | | `data-active` | present | .drawer-wrapper | Scaled back by a scaleBackground drawer. | | `data-drawer-no-drag` | set by you | any element inside | A press here never starts a drag. Set it to x or y to block only that axis. | | `--drawer-x, --drawer-y` | px | .drawer | The panel's offset from its resting place, while dragging and for snap points. | | `--drawer-progress` | 0 to 1 | .drawer, .drawer-wrapper | 1 open, 0 closed; follows the drag. | | `--nested-drawers` | count | .drawer | Drawers open inside this one. | | `data-nested-drawer-swiping` | present | .drawer | A drawer opened from inside this one is being dragged; this one follows it forward (--drawer-nested-progress, 1 to 0). | | `--drawer-frontmost-height` | px | .drawer | The height of the drawer open inside this one. | | `data-nested` | present | .drawer-overlay | This drawer was opened from inside another. | | `data-swipe-dismiss` | present | .drawer | A swipe closed it; set through the exit animation. | | `--drawer-swipe-strength` | 0.1 to 1 | .drawer | Set when a swipe closes it: a faster fling gives a smaller value and a shorter exit. | | `--drawer-swipe-movement-x, --drawer-swipe-movement-y` | px | .drawer | How far a drag has moved the panel from where it rests. | | `--drawer-swipe-progress` | 0 to 1 | .drawer, .drawer-backdrop | 0 at rest, 1 at the closed edge. | | `--drawer-height` | px | .drawer | The panel's height. | | `--drawer-snap-point-offset` | px | .drawer | How far the active snap point leaves the panel translated toward its edge. | | `--drawer-inset` | length | .drawer (set by the caller) | Floats the panel that far off the viewport edges, with every corner rounded. 0 by default. | | `--drawer-overlay-min-opacity` | 0 to 1 | .drawer or .drawer-backdrop (set by the caller) | A floor for the backdrop's opacity, at every snap point and during a drag. Unset, 0.5 with snap points and 0 without. | | `data-swipe-opened` | present | .drawer, .drawer-backdrop | While a drawer the swipe area opened is open: it entered with the finger, not its enter animation. | | `data-disabled` | present | .drawer-swipe-area | swipeAreaDisabled is set. | | `data-slot` | `"drawer-overlay" \| "drawer-content"` | .drawer-backdrop, .drawer | The part's name. | | `data-fixed` | present | .drawer | fixed is keeping the panel's top in place above the keyboard; --drawer-fixed-top holds it. | | `data-swiping` | present | .drawer-swipe-area | While a swipe on the swipe area runs. | | `data-swipe-direction` | `"up" \| "down" \| "left" \| "right"` | .drawer-swipe-area | The swipe that opens the drawer. | | `--drawer-bleed-background` | color | .drawer | Set it to change the fill past the panel's edge, shown when a drag lifts the panel past fully open. Defaults to the panel background. | ## Accessibility - The overlay is a native `` opened with showModal(): role dialog, the top layer, and an inert page behind it. - aria-modal="true", aria-labelledby (the title) and aria-describedby (the description) are set on it. - Focus moves in on open, is trapped while modal and returns to the trigger on close. - Dragging is a pointer convenience: Escape, a press outside, DrawerClose and the optional close button do the same from the keyboard. Without snap points the handle is decorative (aria-hidden). With them it is a button named for what Enter does (Expand drawer, Close drawer), in the Tab order, and the arrows, Home and End move between snap points. - A drawer resting at a low snap point never focuses a control below the viewport: focus goes to the first control it shows, or the panel. ## See also - [Button](button): A button or a link that looks like one, in six variants and four sizes. - [AlertDialog](alert-dialog): A modal that interrupts with something important and waits for an answer. - [Sheet](sheet): A dialog that slides in from an edge of the screen, for content that complements the page.