# lockScroll Stops the page scrolling under a modal. Locks nest: the page unlocks when the last lock is released, so a dialog opened from a dialog is safe. The lock sets `overflow: hidden` on ``, so it captures no events: every scroller inside the modal keeps scrolling natively, pinch zoom still works, and the scrollbar's width is added to the body's right padding so content does not shift when the scrollbar disappears. ```ts Signatures function lockScroll(opts?: ScrollLockOptions): () => void; function scrollLockCount(): number; ``` `lockScroll` returns the unlock function; calling it twice is harmless. ## Options | Option | Type | Default | What it does | |---|---|---|---| | `removeScrollBar` | `boolean` | `true` | Hide the page's scrollbar (`overflow: hidden`, gap compensated). `false` keeps it on screen and blocks wheel, touch and key scrolling of the page instead. | With the scrollbar removed, its width is published as `--scrollbar-gap` on `` for fixed elements that need the same compensation: ```css app/shared/styles/page.css .site-header { padding-right: calc(var(--space-4) + var(--scrollbar-gap, 0px)); } ``` A root with `scrollbar-gutter: stable` keeps its gutter, so no padding is added and `--scrollbar-gap` is `0px`. With `removeScrollBar: false` the page does not scroll by wheel, touch or keys, while a scroller that can still move in that direction takes the gesture as usual. A scroll key is left alone only when the focused element itself uses it: a field, a slider's arrows, a button's Space. A pinch (Ctrl+wheel, two fingers) is never blocked. When any held lock removes the bar, the page uses `overflow: hidden` as above. ## In a template of your own ```ehtml app/shared/templates/overlay/index.ehtml import { lockScroll } from "@elements/ui/behaviors"; interface OverlayState { unlock?: () => void; }
ui.unlock = lockScroll()} onremove={() => ui.unlock?.()}>
``` ## Writes `data-scroll-locked` on `` while any lock is held. With the scrollbar removed: `overflow: hidden` on ``, the scrollbar width added to the body's `padding-right`, and `--scrollbar-gap` on ``. With `removeScrollBar: false`, none of those: wheel, touch and key listeners on the document instead. ## Used by [Combobox](../templates/combobox), [Dialog](../templates/dialog), [DropdownMenu](../templates/dropdown-menu), [ContextMenu](../templates/context-menu), [Menubar](../templates/menubar), [Popover](../templates/popover), [Select](../templates/select).