π react-scroll-locky was replaced by react-remove-scroll π
π Prevents page from being scrolled. Or any other "not permitted" container.
π‘ Hides scrollbars, preserving page width.
π€ Works on any desktop or mobile browser.
π¦ All features are hidden inside.
π« Stands more that one instance.
π€ Supports nested locks
π₯ Supports nested scrollable elements.
This is one line solution for the problem.
All due to React-Locky it uses underneath
this could be dangerous for focus state management. Consider use more composite library - react-focus-on - to handle the every edge case.
- focus
- scroll
- aria (inert)
I've create react-remove-scroll - a smaller version of this library.
Just wrap anything with ScrollLocky
, which accepts only one prop - "enabled"
There is only a few pros to configure
noRelative
- do not apply "position:relative" on body.noImportant
- do not apply "!important" to any rules.className
- className for a internal divheadless
- enables "no-div" mode (will pick the first DOM node-inside)enabled
- allows to disable Lock behavior (CSS modification and Locky), keeping it rendered.isolation
- allows to disable event isolation, preventing onlyscroll
events, not everything outside target node (default behaviour). Useisolation:false
if you have some "shadow" underneath modal, to catch and redirect all events.gapMode=[padding|margin(default)]
- gap policy, to control the way scrollLocky generatethe gap
instead of scrollbars. This option affects how absolutely positioned elements will work:- gapMode="padding" - "right:0" will be on window right (will jump on scroll removal)
- gapMode="margin" - "right:0" will be in constant position (will not jump, but leave a gap)
import {ScrollLocky} from 'react-scroll-locky';
<Modal>
<ScrollLocky>
<MyContent>
Anything!
</MyContent>
</ScrollLocky>
</Modal>
To hide body scrollbars only (does not disable scroll on scrollable container, or body scroll on iOS) use HideBodyScroll
component
import {HideBodyScroll} from 'react-scroll-locky';
<HideBodyScroll noRelative noImportant gapMode/> // body scrollbar is hidden
You may have more than one active Lock on the page:
- Only first Lock is
real
. Only it hides the scrollbars. - Only the last Lock is
active
. Only last-mounted Locky is working, silencing the rest of a page. - To have more that one active lock - consider using
HideBodyScroll
+react-locky
directly.
- "padding" - for the simple use. It will keep scroll-bar-gap for the normal elements, letting absolutely or fixed positioned elements hit the right-most window edge.
- "margin" - for the advanced use. Will always preserve the gap, letting only the
fixed
positioned elements fill the while page(preffered mode)
Default Gap Mode is "margin", it would fit for almost anyone.
But if you have another margin on your body (please dont), or have width:100%
on the body - it would not.
Then, and only then use gapMode="padding"
, and dont forget to add box-sizing: border-box;
to include paddings, we are going to set, to your width.
(and don't send paddings on body, then).
To fill the gap with absolute
positioned elements - use another exposed component.
Special component - ScrollLockyPane
will help maintain the right "right" position.
Alternatively - use react-scroll-locky-edge-right
class, to set proper right border for a container.
import {ScrollLocky, ScrollLockyPane} from 'react-scroll-locky';
// position:absolute, left:0, right: -"gap"px
<ScrollLockyPane>
// your modal inside
<Modal>
<ScrollLocky>
<MyContent/>
</ScrollLocky>
</Modal>
</ScrollLockyPane>
ScrollLockyPane
will "return" the "consumed" width to the component.
- If you need multiple locks to be active in a same time - just do it. They will work together.
There is a medium article about preventing the body scroll - How to fight the scroll
For a good modals you also need a proper Focus Management Library. Use react-focus-lock to complete the picture.
- react-focus-on - Finite Modal creator (uses Scroll-Locky) underneath.
- react-locky - React event canceler
- react-scrolllock - React scroll lock
- scroll-lock - DOM scroll lock
MIT