Skip to content

Sheet

Edit profile

Make changes to your profile here. Click save when you are done.

<button class="btn btn-outline" data-pk-dialog-open="filters">Open sheet</button>
<dialog class="sheet" id="filters" data-side="right">
<div class="sheet-header">
<h3 class="sheet-title">Edit profile</h3>
<p class="sheet-description">Make changes to your profile here.</p>
</div>
<div class="sheet-body"></div>
<div class="sheet-footer"></div>
</dialog>

A sheet is a <dialog> pinned to an edge, so it is modal for free: the page behind it is inert, Escape closes it, and focus is trapped and restored by the browser.

ClassPart
.sheetThe panel
.sheet-headerTitle and description
.sheet-titleNames the panel, and labels it for screen readers
.sheet-descriptionSupporting line
.sheet-bodyThe scrolling middle
.sheet-footerActions, pushed to the bottom
.sheet-closeThe close button in the corner
AttributeMeaning
data-side="right"Default. Also left, top, bottom
data-side="inline-start" / "inline-end"Sides that follow the reading direction
data-pk-dialog-openOn the trigger: the id of the sheet
data-pk-dialog-closeOn a control inside: closes, with an optional return value
data-pk-staticClicking the backdrop does not close it

Top

Press Escape to close.

Right

Press Escape to close.

Bottom

Press Escape to close.

Left

Press Escape to close.

left and right are literal: a right sheet stays on the right in Arabic. Use inline-start and inline-end when the panel should follow the reading direction instead.

Width is not baked in — a side sheet is three quarters of the screen up to sm, and anything beyond that is yours to set.

Filters

A sheet is as wide as you make it.

Set dir="rtl" on the page or on any subtree. Named sides stay physical; the inline-* sides swap. See the button page for a live example.

  • .sheet-title labels the panel through aria-labelledby, so it is announced by name. Without a title, give the sheet an aria-label.
  • The browser makes it modal. showModal() marks the rest of the page inert, traps Tab, and returns focus to whatever opened it — none of which needs a focus-trap library.
  • A close button needs text. The × is an icon; keep the .sr-only label beside it.
  • Do not put the only way out in the corner. Escape and the backdrop already close it; a visible Cancel is still worth having when there is something to lose.
  • The body scrolls, not the panel. Keeping the header and footer fixed means the actions stay reachable in a long form.