Suggest an editImprove this articleRefine the answer for “Blocking page scroll”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**The simplest and most reliable way is to set `overflow: hidden` on `<body>` (or `<html>`), usually through a CSS class such as `.no-scroll`.** To stop the page jumping to the top when it was already scrolled, combine the lock with a position freeze: `position: fixed` plus `top: -scrollY`, and restore the offset with `window.scrollTo()` when unlocking. On iOS Safari touch scrolling sometimes slips past `overflow: hidden`, so there you also intercept `touchmove` with `{ passive: false }`. ```javascript document.body.style.overflow = 'hidden'; // block scrolling document.body.style.overflow = ''; // unblock ``` **Key point:** `overflow: hidden` blocks scrolling, `position: fixed` preserves the offset, `touchmove` with `preventDefault()` covers the mobile case.Shown above the full answer for quick recall.Answer (EN)Image**Page scrolling is blocked through CSS: you set `overflow: hidden` on `<body>` (or `<html>`), and the page stops scrolling both with the mouse wheel and with a finger.** For a complete solution this trick is combined with freezing the scroll offset and with separate handling of mobile touch scrolling. ## Theory ### TL;DR - The basic approach: `document.body.style.overflow = 'hidden'`, and `overflow = ''` to release it. - It is cleaner to do this with a `.no-scroll` CSS class instead of inline styles. - If the page was already scrolled, plain `overflow: hidden` can make the content jump; `position: fixed` with `top: -scrollY` fixes that. - After unblocking, the offset is restored with `window.scrollTo()`. - On iOS Safari you sometimes need a `touchmove` listener with `{ passive: false }` and `preventDefault()`. - The techniques combine: a class, plus the position freeze, plus the mobile safeguard. ### Quick example ```javascript function disableScroll() { document.body.style.overflow = 'hidden'; } function enableScroll() { document.body.style.overflow = ''; } openModalBtn.addEventListener('click', disableScroll); closeModalBtn.addEventListener('click', enableScroll); ``` ### The simplest way: overflow: hidden The browser lets you block scrolling of the whole page if you set `overflow: hidden` on `<body>` (or `<html>`). ```javascript document.body.style.overflow = 'hidden'; // block scrolling ``` To put everything back: ```javascript document.body.style.overflow = ''; // unblock ``` This is the **most common approach**: the page stays where it is, and neither the mouse wheel nor touch scrolling moves it. For the vast majority of interfaces (modals, burger menus, overlays) that is enough. ### Preserving the offset so the content does not jump If the page was scrolled and you simply apply `overflow: hidden`, the content can **jerk** because the scrollbar disappears. Here is the more correct variant, with the position frozen: ```javascript function disableScroll() { const scrollY = window.scrollY; document.body.style.position = 'fixed'; document.body.style.top = `-${scrollY}px`; document.body.style.width = '100%'; } function enableScroll() { const scrollY = document.body.style.top; document.body.style.position = ''; document.body.style.top = ''; window.scrollTo(0, parseInt(scrollY || '0') * -1); } ``` Now the page stays exactly where the user stopped, and after unblocking it returns to the same point. `width: 100%` is needed because `position: fixed` takes `<body>` out of the flow, and it may shrink to the width of its content. ### A CSS class instead of inline styles Handy when you open modals often: ```css /* styles.css */ .no-scroll { overflow: hidden; } ``` ```javascript document.body.classList.add('no-scroll'); // block document.body.classList.remove('no-scroll'); // unblock ``` This is clean, readable and easy to scale: all the locking rules live in one place in CSS, and JS only toggles the class. ### Blocking scroll on mobile devices On iOS, `overflow: hidden` **sometimes does not help** with touch scrolling inside `<body>`. In that case you intercept the `touchmove` event: ```javascript function preventTouchScroll(e) { e.preventDefault(); } function disableScrollMobile() { document.addEventListener('touchmove', preventTouchScroll, { passive: false }); } function enableScrollMobile() { document.removeEventListener('touchmove', preventTouchScroll); } ``` The `{ passive: false }` option is mandatory here: by default `touchmove` listeners on `document` are treated as passive, and `preventDefault()` inside them does nothing. This technique can be combined with `overflow: hidden` for reliability. ### Summary table | Goal | Technique | Note | | --- | --- | --- | | Just block it | `document.body.style.overflow = 'hidden'` | Fits the vast majority of cases | | Preserve the offset | `position: fixed` plus `top = -scrollY` | No jump when the lock is removed | | Frequent use | Adding a `.no-scroll` class | Convenient for modals | | Mobile reliability | `touchmove` plus `preventDefault()` | For iOS Safari | > **Just remember:** `overflow: hidden` blocks scrolling, `position: fixed` freezes the offset, `touchmove` with `preventDefault()` protects against touch scrolling on mobile. ### Common mistakes - Applying `overflow: hidden` only to `<html>` or only to `<body>` and being surprised that some browsers still scroll. Checking both elements is safer. - Forgetting to release the lock when the modal closes, especially on the error path: the page stays frozen forever. - Using `position: fixed` without saving and later restoring `scrollY`: the user is thrown back to the top of the page. - Omitting `width: 100%` with `position: fixed`, so the layout narrows and the content jumps. - Registering `touchmove` without `{ passive: false }`: the browser ignores `preventDefault()` and logs a warning. - Blocking `touchmove` on the whole document and killing scrolling inside the modal itself along with the page. Check the event target or attach the listener narrowly. - Treating the lock as a global boolean: with several modals you need a counter of open windows, otherwise closing one unlocks the page behind another.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.