CSS

How to: Prevent Body From Scrolling

After I accidentally stumbled upon the solution to “preventing body scrolling when overlay is on” by trying too many different things again and again, I wasn’t able to explain exactly why this works.

Almost 2 years later, after another week-long painful bug with scrolling problems, and trying too many things all over again, I finally came up with the gist of all “prevent some div from scrolling” problems.

Namely:

  • don’t allow body to be taller than window, and
  • have the scrolled-div and don’t-let-me-scroll-div as siblings instead of parent and child, so that no propagation of scrolls can happen

To achieve limited body height, we can either go:

  1. The natural way:
    • html/body: height: 100%; which renders body exactly at window height
    • at the same time, set a 100% height and overflow: auto; on all direct child elements of body
    • the reason 100% height alone doesn’t work is that: the default option for overflow is visible. Even though content after an overflow-visible element won’t be pushed down by the overflow, parent element’s height will be stretched all the same.
  2. The forceful way:
    • set all too-tall child elements of body to be:
    • position: absolute/fixed; top: 0; bottom: 0;
    • basically making sure none of them can put their toes across the boundary (border of window), therefore ensuring that nothing can sneakily stretch up body height
    • and of course, overflow: auto; on them too, because otherwise body is still stretched.

Example 1: This Demo

  • result:
    • scrolling on overlay won’t scroll content layer
  • how-to:
    • height of html/body is 100%
    • nothing inside body has a height taller than window
    • overlay div and content page are siblings.

Example 2: Kendo-ui’s auto-complete demo page.

  • result:
    • scrolling inside the autocomplete dropdown won’t scroll the page, yet
    • scrolling outside of dropdown scrolls the page which triggers dropdown close.
  • how-to:
    • in an in-page script tag inside <head>, using JavaScript to calculate and manually set #main’s height on resize, thereby always keeping body height at window height
    • dropdown div and #main content div are siblings.

Structure your html wisely, and no JavaScript shall be necessary.

May this issue never haunt any of us ever again.

Standard