react-remove-scroll

repository·master·Indexed 21 days ago

https://github.com/thekashey/react-remove-scroll

A React library (v2.7.2) that disables scrolling on the document body and elements outside of a specified container, effectively locking the scroll to a specific component. It supports mouse and touch devices, vertical and horizontal scrolling, nested scrollable elements, and React Portals. The library includes a sidecar pattern for optimized bundle size and utility classes via RemoveScroll.classNames to handle position:fixed elements.

Tokens
2.8K
Snippets
7
Records
15
Agent score
73%

What's inside react-remove-scroll

  1. Performance considerations for react-remove-scroll

    master

    react-remove-scroll uses non-passive event listeners to ensure synchronous scroll/touch handling. This is necessary for the library to function correctly but may trigger warnings in Chrome DevTools and can impact scrolling performance.

    Optimization Tip: If you are dealing with very large scrollable areas, consider using the noIsolation prop to mitigate performance impacts.

  2. Install and use react-remove-scroll

    master

    react-remove-scroll disables scrolling on everything outside of the provided children node. It is compatible with mouse and touch devices, supports both vertical and horizontal scrolling, and manages the document scrollbar to prevent layout shifts. It also supports nested scrollable elements and React Portals.

    To use it, wrap the content that should remain scrollable with the RemoveScroll component.

    import {RemoveScroll} from 'react-remove-scroll';
    
    <RemoveScroll>
      Only this content would be scrollable
    </RemoveScroll>
  3. Handle the Internal Div and forwardProps

    master

    By default, RemoveScroll creates an internal div to capture events. You can either style this div using className or remove it entirely by using forwardProps on a child element.

    Option 1: Using className on the component

    <RemoveScroll className="scroll">
      Only this content would be scrollable
    </RemoveScroll>

    Option 2: Using forwardProps to inject props into a child

    <RemoveScroll forwardProps>
      <div className="scroll">
        Only this content would be scrollable
      </div>
    </RemoveScroll>
  4. Handle `position:fixed` elements with RemoveScroll

    master

    To ensure position:fixed elements are sized correctly when using RemoveScroll, you must apply specific class names provided by the library. This allows elements to behave as if they have width: 100% or specific alignments (like right: 0) even when the body scroll is disabled.

    Use RemoveScroll.classNames to access these utility classes:

    • RemoveScroll.classNames.fullWidth
    • RemoveScroll.classNames.zeroRight
    import {RemoveScroll} from 'react-remove-scroll';
    
    // To make an element behave like width: 100%
    <div className={cx(classWithPositionFixed, RemoveScroll.classNames.fullWidth)} />
    
    // To make an element behave like right: 0
    <div className={cx(classWithPositionFixed, RemoveScroll.classNames.zeroRight)} />
  5. Use forwardProps to control child rendering

    master

    The RemoveScroll component has two modes for handling children, determined by the forwardProps logic:

    1. Standard Mode (forwardProps={false}): The component wraps its children in a div. In this mode, children should be a ReactNode.
    2. Forwarding Mode (forwardProps={true}): The component forwards all props to a single child node. In this mode, children must be a ReactElement.
  6. Use sidecar for optimized bundle size

    master

    To reduce the initial bundle size, you can use the sidecar pattern. This allows the heavy logic of react-remove-scroll to be loaded only when needed.

    1. Import sidecar from react-remove-scroll.
    2. Import RemoveScroll from react-remove-scroll/UI.
    3. Create a sidecar function that dynamically imports react-remove-scroll/sidecar.
    4. Pass the sidecar to the sideCar prop of RemoveScroll.
    import {sidecar} from "react-remove-scroll";
    import {RemoveScroll} from 'react-remove-scroll/UI';
    
    const sidecar = sidecar(() => import('react-remove-scroll/sidecar'));
    
    <RemoveScroll sideCar={sidecar}>
      Will load logic from a sidecar when needed
    </RemoveScroll>
  7. Configure RemoveScroll props

    master

    The RemoveScroll component accepts the following props:

    PropTypeDefaultDescription
    childrenReactNodeThe content that remains scrollable.
    enabledbooleanActivate or deactivate component behavior without removing it.
    allowPinchZoombooleanfalseEnables "pinch-n-zoom" behavior. Note: this may break scroll isolation.
    noRelativebooleanfalsePrevents setting position: relative on the body.
    noIsolationbooleanfalseDisables outer event capturing. Useful if using shadowboxes, but React-friendly by default.
    inertbooleanfalseWarning: Disables all events on the rest of the page using pointer-events except for the Lock and shards. Not friendly with React Portals; use only in rare cases.
    forwardPropsbooleanForwards all props to the children element.
    classNamestringApplies a class name to the internal div used for event capturing.
    removeScrollBarbooleanControls scrollbar removal. Set to false to keep the scrollbar visible (though wheel/touch scroll will still be disabled).
  8. Configure RemoveScroll component props

    master

    The RemoveScroll component accepts several props to control how scroll locking and event isolation behave.

    Key configuration options include:

    • enabled: Switches the behavior of the component on or off.
    • removeScrollBar: Controls whether the body scroll bar is removed (defaults to false).
    • noRelative: Prevents `position=
  9. Use the RemoveScroll component

    master

    The RemoveScroll component is the primary entrypoint for the library. It is used to prevent scrolling on the body and other elements when a specific part of the UI (like a modal or overlay) is active. It can be used as a component that wraps content or as a combination of features to manage scroll locking effectively.

    import { RemoveScroll } from 'react-remove-scroll';
    
    function MyComponent() {
      return (
        <RemoveScroll>
          <div>
            {/* Content inside here will be visible, but the background will not scroll */}
            <h1>Modal Content</h1>
          </div>
        </RemoveScroll>
      );
    }
  10. Configure event isolation and inert behavior

    master

    You can control how events outside the lock are handled using noIsolation and inert:

    • noIsolation: Disables event isolation (suppressing of events happening outside of the Lock). Defaults to false.
    • inert: Enables complete Lock isolation using pointer-events:none for anything outside the Lock. This is useful for strict isolation but should be used carefully. Defaults to false.
    • allowPinchZoom: Allows pinch-zoom gestures, though scroll behavior may vary. Defaults to false.
  11. Configure gapMode and shards

    master

    When the scrollbar is removed, a 'gap' is created. You can control how this gap is filled and which elements are included in the lock:

    • gapMode: Controls how the gap is filled. Options are 'padding' or 'margin'. Defaults to 'margin'.
    • shards: An array of refs to other Elements that should be considered as part of the Lock. This allows multiple disconnected DOM nodes to be treated as a single locked area.