Rooks
HooksAnimation & Timing

useLockBodyScroll

Sets document.body overflow to hidden while a condition is true.

About

useLockBodyScroll prevents the document body from scrolling while isLocked is true. It is commonly used while a modal or drawer is open.

Examples

import { useState } from "react";
import { useLockBodyScroll } from "rooks";

export default function ScrollLockDemo() {
  const [open, setOpen] = useState(false);
  useLockBodyScroll(open);

  return (
    <section>
      <button type="button" onClick={() => setOpen(true)}>
        Open dialog
      </button>
      {open && (
        <div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
          <h2 id="dialog-title">Example dialog</h2>
          <button type="button" onClick={() => setOpen(false)}>
            Close
          </button>
        </div>
      )}
    </section>
  );
}

Parameters

isLocked: boolean is required.

Return value

The hook returns void.

Behavior and lifecycle

When locked, the effect reads the body's computed overflow, writes inline overflow: hidden, and restores the computed value when unlocked or unmounted. Multiple simultaneous hook owners can restore over one another, so coordinate scroll locking at one layer. The hook does not preserve the exact prior inline declaration separately and does not compensate for scrollbar-width layout shifts.

Compatibility and accessibility

Effects do not run on the server, but the client effect requires window and document.body. Scroll locking alone does not make a modal accessible: move focus into it, contain focus, restore focus on close, label it, and make the background inert or otherwise unavailable.

On this page