Skip to content

Drawer <l-drawer>

Drawers display supplementary content in a panel that slides in from a screen edge. Commonly used for navigation menus, filters, and detail views without leaving the current page.

HTML tag<l-drawer>
Native HTML
Progressive
Custom
Shadow DOM
Custom Element · Shadow DOM

Options

Basic

Open with command="--show" on a trigger button. Slides in from the left.

This drawer slides in from the left.

Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-default"
>
  Open drawer
</button>

<l-drawer
  id="drawer-default"
  title="Drawer"
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-default"
  ></button>
  <p>This drawer slides in from the left.</p>
</l-drawer>

Placement

Set placement to control which edge the drawer slides from. Defaults to start (inline-start). Use placement="end" for the inline-end edge or placement="bottom" for the block-end edge.

End

This drawer slides in from the right.

Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-end"
>
  Open right drawer
</button>

<l-drawer
  id="drawer-end"
  title="Drawer"
  placement="end"
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-end"
  ></button>
  <p>This drawer slides in from the right.</p>
</l-drawer>

Bottom

This drawer slides in from the bottom.

Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-bottom"
>
  Open bottom drawer
</button>

<l-drawer
  id="drawer-bottom"
  title="Drawer"
  placement="bottom"
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-bottom"
  ></button>
  <p>This drawer slides in from the bottom.</p>
</l-drawer>

Light dismiss

Add light-dismiss to close when the backdrop is clicked.

Click the backdrop or press Escape to close.

Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-light-dismiss"
>
  Open drawer
</button>

<l-drawer
  id="drawer-light-dismiss"
  title="Drawer"
  light-dismiss
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-light-dismiss"
  ></button>
  <p>Click the backdrop or press Escape to close.</p>
</l-drawer>

Examples

Mobile navigation menu with link items.

Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-nav"
>
  Menu
</button>

<l-drawer
  id="drawer-nav"
  title="Navigation"
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-nav"
  ></button>
  <nav>
    <ul class="flex flex-col gap-1">
      <li>
        <a
          href="#"
          class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-gray-100"
          >Home</a
        >
      </li>
      <li>
        <a
          href="#"
          class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-gray-100"
          >Products</a
        >
      </li>
      <li>
        <a
          href="#"
          class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-gray-100"
          >Orders</a
        >
      </li>
      <li>
        <a
          href="#"
          class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-gray-100"
          >Customers</a
        >
      </li>
      <li>
        <a
          href="#"
          class="flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium hover:bg-gray-100"
          >Settings</a
        >
      </li>
    </ul>
  </nav>
</l-drawer>

Filters

Right-side filter panel with a footer for actions.

Category
Price range
Code
html
<button
  type="button"
  class="l-button"
  command="--show"
  commandfor="drawer-filters"
>
  Filters
</button>

<l-drawer
  id="drawer-filters"
  title="Filters"
  placement="end"
  style="--size: 380px"
>
  <button
    slot="close"
    type="button"
    class="l-close"
    data-appearance="ring"
    aria-label="Close"
    command="--hide"
    commandfor="drawer-filters"
  ></button>
  <div class="flex flex-col gap-6">
    <fieldset>
      <legend class="text-sm font-medium mb-2">Category</legend>
      <div class="flex flex-col gap-2">
        <label class="flex items-center gap-2 text-sm"
          ><input
            type="checkbox"
            checked
          />
          Electronics</label
        >
        <label class="flex items-center gap-2 text-sm"><input type="checkbox" /> Clothing</label>
        <label class="flex items-center gap-2 text-sm"><input type="checkbox" /> Books</label>
      </div>
    </fieldset>
    <fieldset>
      <legend class="text-sm font-medium mb-2">Price range</legend>
      <div class="flex flex-col gap-2">
        <label class="flex items-center gap-2 text-sm"
          ><input
            type="radio"
            name="price"
            checked
          />
          All prices</label
        >
        <label class="flex items-center gap-2 text-sm"
          ><input
            type="radio"
            name="price"
          />
          Under $50</label
        >
        <label class="flex items-center gap-2 text-sm"
          ><input
            type="radio"
            name="price"
          />
          $50 – $100</label
        >
        <label class="flex items-center gap-2 text-sm"
          ><input
            type="radio"
            name="price"
          />
          Over $100</label
        >
      </div>
    </fieldset>
  </div>
  <menu slot="footer">
    <button
      type="button"
      class="l-button"
      command="--hide"
      commandfor="drawer-filters"
    >
      Cancel
    </button>
    <button
      type="button"
      class="l-button"
      data-variant="primary"
    >
      Apply
    </button>
  </menu>
</l-drawer>

Accessibility

Criteria

Role

Rendered as a native <dialog> in the shadow root — built-in dialog role and modal semantics

WCAG4.1.2
RGAA7.1
Accessible name

The title property is rendered as an <h2> inside the drawer header

WCAG4.1.2
RGAA11.1
Focus management

Focus is trapped inside the modal; moves to the first focusable element on open

WCAG2.4.3
RGAA10.7
Focus restoration

Focus returns to the trigger element when the drawer closes

WCAG2.4.3
Close button

Consumer provides the close button via slot="close" with aria-label="Close"

WCAG2.4.6
Motion

Slide animation respects prefers-reduced-motion

WCAG2.3.3

Keyboard interactions

Escape
Closes the drawer
Tab
Cycles focus through focusable elements inside the drawer
ShiftTab
Cycles focus backward through focusable elements inside the drawer

API reference

Importing

js
import 'luxen-ui/drawer';

Attributes & Properties

titleAttribute
Drawer title rendered in the header as an <h2>
openAttribute
Whether the drawer is open. Reflects to attribute
light-dismissAttribute
Close when the backdrop is clicked
placementAttribute
Edge the drawer slides from: start (default), end, or bottom

Commands

Open and close the drawer by toggling its open property, or via the Invoker Commands API from any light-DOM button. Custom commands must start with --.

--showCommand
Sets open = true
--hideCommand
Sets open = false

Events

showEvent
Fired when the drawer opens
after-showEvent
Fired after the open animation completes
hideEvent
Fired when the drawer is about to close. Cancelable — call event.preventDefault() to keep it open
after-hideEvent
Fired after the close animation completes

Slots

(default)Slot
Body content
closeSlot
Close button (typically <button class="l-close">)
footerSlot
Footer actions

CSS parts

dialogPart
The native <dialog> element
headerPart
The header wrapper containing the title and close slot
titlePart
The drawer title heading
bodyPart
The body wrapper around the default slot
footerPart
The footer wrapper around the footer slot

CSS custom properties

--sizeName
Drawer size on the axis perpendicular to its edge (width for start/end, height for bottom). Default 320px
--border-radiusName
Border radius on the inner edges. Default 0.75rem
--show-durationName
Open transition duration. Default 200ms
--hide-durationName
Close transition duration. Default 200ms
--backdropName
Backdrop color