react-ios-scroll-lock
Version:
A lightweight CSS-only scroll lock solution for iOS Safari and Android
91 lines (60 loc) • 3.13 kB
Markdown
# react-ios-scroll-lock
The initial idea was to lock the body scroll on iOS Safari whenever we see fit, turns out we made something that works everywhere on the web<br />This was achieved with overscroll-behaviour css property
Most workarounds involve JavaScript, touchmove event listeners, or weird side effects. I wanted something simpler — so I built react-ios-scroll-lock: a CSS-only scroll lock component that works across iOS, Android, and all major browsers.
⚡️ Pure CSS – no JS scroll hacks (JS used only to measure device height and detect iOS)
🧘 Doesn’t interfere with touch or scroll events
📱 Works on iOS, Android, and desktop
🪶 Minimal performance cost
🧩 Easy to plug into any React project
### Medium Article: [https://stripearmy.medium.com/i-fixed-a-decade-long-ios-safari-problem-0d85f76caec0](https://stripearmy.medium.com/i-fixed-a-decade-long-ios-safari-problem-0d85f76caec0)
### Demo: (desktop demo will be available soon) [https://stripearmy.github.io/ios-scroll-lock-demo/](https://stripearmy.github.io/ios-scroll-lock-demo/)
### Demo (simple yes/no modal): [https://stripearmy.github.io/ios-scroll-lock-demo/simple.html](https://stripearmy.github.io/ios-scroll-lock-demo/simple.html)
### Demo (modal with scrollable content): [https://stripearmy.github.io/ios-scroll-lock-demo/scrollable.html](https://stripearmy.github.io/ios-scroll-lock-demo/scrollable.html)
## Installation
$ npm install react-ios-scroll-lock
or
$ yarn add react-ios-scroll-lock
## Usage
```javascript
// Import react-ios-scroll-lock
import {IosScrollLock} from 'react-ios-scroll-lock';
// Import css
import 'react-ios-scroll-lock/css';
<IosScrollLock>
Your content goes here
</IosScrollLock>
```
### Trigger the open state by modifying the "isOpen" (boolean) attribute <br /><br />Note: Is disabled by "isInline" attribute
```javascript
<IosScrollLock isOpen={true}>
```
### Tip: if your CSS breaks the functionality of IosScrollLock just render it using React Portal
```javascript
{createPortal(
<IosScrollLock isOpen={true}>
Your content goes here
</IosScrollLock>,
document.body
)}
```
### Pass your custom className(s) by using the optional "className" attribute
```javascript
<IosScrollLock className="yourCustomClassName">
```
### Pass your custom background color by using the optional "bgColor" attribute
```javascript
<IosScrollLock bgColor="#000">
// or
<IosScrollLock bgColor="rgba(0, 0, 0, 0.5)">
// or
<IosScrollLock bgColor="var(--yourCustomBgColor)">
```
### Render the component contents ONLY wherever you want by using the optional "isInline" (boolean) attribute<br /><br />Note: Disables the effects of "isOpen" attribute<br/><br/>Can be useful if you don't want to render same component/content twice, once inside a page and once inside a modal, you can achieve both functionalities by utilizing "isInline"
```javascript
<IosScrollLock isInline={true}>
```
## Contributing
Pull requests are welcome. For major changes, please open an issue first
to discuss what you would like to change.
## License
[MIT](https://choosealicense.com/licenses/mit/)