useBodyScrollFreeze

An imperative hook to disable body scrolling on specific axes while maintaining the user's current scroll position.

Warning

This hook uses position: fixed on the body to prevent "scroll jumping" on iOS Safari. While effective, ensure your layout doesn't rely on absolute positioning relative to the body that might break during the freeze.

Important

Always pair freeze() with unfreeze(). Although the hook attempts to cleanup on unmount, manual imperative calls should be handled carefully to avoid leaving the UI in a locked state.

Installation

bash

Description

The useBodyScrollFreeze provides a mechanism to lock the background scroll, which is essential for modals, drawers, or full-screen overlays. Unlike simple overflow: hidden implementations, this hook uses position: fixed logic to ensure the page doesn't "jump" to the top when locked and restores the exact scroll position and original styles upon unmounting or unfreezing.

Parameters

NameTypeDescription
options.axis'x' | 'y' | 'both'Specifies which axis should be locked. Default: 'y'.

Return values

NameTypeDescription
freeze(options?: BodyScrollFreezeOptions) => voidImperative function to apply the scroll lock to the body element.
unfreeze() => voidReverts the scroll lock by resetting the body element styles.

Demo

Body Scroll Freeze

Source code

tsx