Skip to content

Page transitions

<div data-scrollsheet-background>{/* your page content */}</div>
<Sheet.Root backgroundEffect="scale" detents={['full']}>

Mark your page wrapper data-scrollsheet-background, then backgroundEffect="scale" scales, insets, and rounds it in sync with the sheet’s own travel, an iOS-style card transition. Paired with a 'full' detent, a sheet becomes a full-screen page that pushes the page behind it back like a stack. 'parallax' shifts the wrapper instead of scaling it. Read --scrollsheet-stack-progress on a parent sheet’s own panel for the equivalent effect between nested sheets.

Mark the wrapper and a full-height bottom sheet gets 'scale' on its own, with no prop: that is how the platform presents a sheet covering the screen. The default only fires when the sheet was opened from inside that wrapper, so a page hosting several independent sheets never moves the wrong one. Desktop drawers dock beside the page and leave it alone, and 'none' opts out.

backgroundRef targets the wrapper directly instead of the data-scrollsheet-background query, for a wrapper you’d rather not stamp an attribute onto, or two sheets on the same page whose document-wide query could otherwise collide:

const pageRef = useRef<HTMLDivElement>(null);
<div ref={pageRef}>{/* your page content, no attribute needed */}</div>
<Sheet.Root backgroundEffect="scale" backgroundRef={pageRef} detents={['full']}>

It skips the marker lookup and its ownership check entirely: an explicit ref is unambiguous about which element it means.