Bootstrap 5 Component

Bootstrap Sheet

Touch-friendly bottom sheet with physics-based spring gestures, backdrop, focus trap, and full keyboard support.

npm install bootstrap-sheet Documentation
01

Declarative API

Add data-bs-toggle="sheet" to any trigger element - no JavaScript required. Close with the data-bs-dismiss="sheet" button, the drag handle, or Escape.

Show code
<button data-bs-toggle="sheet" data-bs-target="#mySheet">
  Open sheet
</button>

<div class="sheet" id="mySheet">
  <div class="sheet-handle" data-bs-drag="sheet"></div>
  <div class="sheet-header">
    <h5 class="sheet-title">Title</h5>
    <button class="btn-close" data-bs-dismiss="sheet"></button>
  </div>
  <div class="sheet-body">...</div>
</div>

No JavaScript - just data attributes

02

Spring Physics

All animations - show, hide, snap-back - are driven by a spring model. springDampingRatio controls bounciness; springResponse controls speed.

Swipe down past 50% of sheet height to dismiss. Drag up against rubber-band resistance - release and the spring snaps you back.

Show code
new BootstrapSheet('#mySheet', {
  gestures: true,
  springDampingRatio: 0.8,
  springResponse: 0.4,
});
0.80
bouncy no bounce overdamped
0.40
fast & snappy slow
03

Backdrop Modes

Three behaviours with a single option. 'static' mode blocks dismissal and triggers a shake animation - tactile feedback that the sheet requires explicit action.

Show code
// Dismissible (default)
new BootstrapSheet('#mySheet', { backdrop: true });

// Static - shake on outside click
new BootstrapSheet('#mySheet', { backdrop: 'static' });

// No backdrop
new BootstrapSheet('#mySheet', { backdrop: false });

Click outside → closes

Click outside → shakes

No overlay

04

Slide Event

slide.bs.sheet fires on every animation frame during drag. detail.ratio runs from 0 (fully open) to 1 (dismissed), letting you synchronize any custom visual to the gesture in real time.

Show code
const mySheet = document.getElementById('mySheet');

mySheet.addEventListener('slide.bs.sheet', (e) => {
  const { ratio, velocity, deltaY } = e.detail;

  // drive any visual with ratio 0→1
  bar.style.width = (ratio * 100) + '%';
});
slide.bs.sheet → ratio -
0 · fully open 1 · dismissed
05

Accessibility

  • ARIA - role="dialog" and aria-modal="true" applied automatically
  • Focus trap - Tab cycles within the sheet; Shift+Tab goes backwards
  • Focus restore - focus returns to the trigger element on close
  • Inert background - page content behind the sheet is made inert
  • Keyboard dismiss - Escape closes the sheet (configurable via keyboard option)
Try it: Tab through the fields, Shift+Tab backwards, Escape to close. Focus returns to the button above.
Basic sheet

Opened with a data attribute - no JavaScript needed.

Close via the × button, the drag handle, or the Escape key.

Spring physics

Drag down past the midpoint to dismiss. Drag up - rubber-band resistance kicks in. Release below the midpoint and the spring snaps back.

Slide event

Drag the handle and watch the ratio bar update live on the page behind this sheet.

Accessibility demo