Skip to content
Removes and disables πŸ“œin a "React" way
TypeScript CSS JavaScript HTML
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.


Type Name Latest commit message Commit time
Failed to load latest commit information.
.storybook more stories Jun 28, 2019
UI fix: cjs sidecar package Jul 2, 2019
__tests__ update tests Jul 2, 2019
example feat: add allowPinchZoom property, fixes #17 Oct 17, 2019
sidecar fix: cjs sidecar package Jul 2, 2019
src feat: add allowPinchZoom property, fixes #17 Oct 17, 2019
stories more stories Jun 28, 2019
.gitignore initial release Jan 18, 2019
.npmignore better margin management Jan 22, 2019
.nvmrc initial release Jan 18, 2019
.size-limit fix: remove self dependency Jun 29, 2019
.travis.yml update CHANGELOG Oct 22, 2019 feat: add allowPinchZoom property, fixes #17 Oct 17, 2019
package.json update CHANGELOG Oct 22, 2019
tsconfig.json more stories Jun 28, 2019
yarn.lock update CHANGELOG Oct 22, 2019


dont even scroll
Build status npm downloads bundle size


NPM version

Disables scroll outside of children node.

  • πŸ–± mouse and touch devices friendly
  • πŸ“ˆ vertical and horizontal
  • πŸ“œ removes document scroll bar maintaining it space
  • βœ… support nested scrollable elements
  • πŸ•³ supports react-portals (uses React Event system)
  • ☠️ it could block literally any scroll anywhere


Just wrap content, which should be scrollable, and everything else would not.

import {RemoveScroll} from 'react-remove-scroll';

  Only this content would be scrollable

RemoveScroll accept following props

  • children
  • [enabled] - activate or deactivate component behaviour without removing it.
  • [allowPinchZoom=false] - enabled "pinch-n-zoom" behavior. By default it might be prevented. However - pinch and zoom might break "scroll isolation", and disabled by default.
  • [noIsolation=false] - disables outer event capturing. Event capturing is React friendly and unlikely be a problem. But if you are using shadowbox of some sort - you dont need it.
  • [inert=false] - ☠️(be careful) disables events the rest of page completely using pointer-events expect the Lock(+shard). React portals not friendly, might lead to production issues. Enable only for rare cases, when you have to disable scrollbars somewhere on the page(except body, Lock and shards).
  • [forwardProps] - will forward all props to the children
  • [className] - className for an internal div
  • [removeScrollBar] - to control scroll bar removal. Set to false, if you prefer to keep it (wheel and touch scroll is still disabled).


  • (🧩 full) 1.7kb after compression (excluding tslib).

  • (πŸ‘ UI) 400b, visual elements only
  • (πŸš— sidecar) 1.5kb, side effects
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

Consider setting -webkit-overflow-scrolling: touch; on a document level for a proper mobile experience.

Internal div

But default RemoveScroll will create a div to handle and capture events. You may specify className for it, if you need, or remove it.

The following code samples will produce the same output

<RemoveScroll className="scroll">
  Only this content would be scrollable
<RemoveScroll forwardProps>
  <div className="scroll"> //RemoveScroll will inject props to this div
    Only this content would be scrollable

Pick the first one if you don't need a second.

Position:fixed elements

To properly size these elements please add a special className to them.

import {RemoveScroll} from 'react-remove-scroll';

// to make "width: 100%"
<div className={cx(classWithPositionFixed, RemoveScroll.classNames.fullWidth)} />

// to make "right:0"
<div className={cx(classWithPositionFixed, RemoveScroll.classNames.zeroRight)} />

See react-remove-scroll-bar documentation for details.

More than one lock

When stacked more is active (default) only one (last) component would be active.

Over isolation

That could happen - you disable scroll on the body, you are suppressing all scroll and wheel events, and you are ghosting the rest of the page by the inert prop.

Only something inside Lock does exists for the browser, and that might be less than you expected.

Dont forget about shard, dont forget - inert is not portals friendly, dont forget - you dont need over isolation in most of the cases.

just be careful!


To do the job this library setup non passive event listener. Chrome dev tools would complain about it, as a performance no-op.

We have to use synchronous scroll/touch handler, and it may affect scrolling performance.

Consider using noIsolation mode, if you have large scrollable areas.

Supported React versions

  • v1 supports React 15/16
  • v2 requires 16.8.0+ (hooks)


This is a refactoring of another library - react-scroll-locky - to make package smaller and more react-portals friendly.

See also

This package is relative smaller(1), more react friendly(2), works with non zero body margins(3), and has a better "overscroll" management.



You can’t perform that action at this time.