DEV Community

Kevin Cameron
Kevin Cameron

Posted on

Modals and Scrollbars

Today while building a modal I experimented with a different layout that solves a few issues with the scrollbar, in a simple way. Jump to the final version, or read on.

Basic Modal

The most basic modal is 2 <div> elements:

  1. an overlay position: fixed; in the <body>
  2. and the content, nested in the overlay


There's an issue with this simple modal: the vertical scrollbar of the main content persists when the modal is opened.

main content scrolling behind modal

Opening a modal should fully switch context away from the underlying content to the modal. Scrolling presentation and interaction need to follow this context switch.

A common solution is to add overflow: hidden on <html> or <body>, removing the scrollbar entirely. This also works if the modal content is scrollable.

Content Shift

Removing the scrollbar fixes one problem, but introduces another: the underlying content shifts position.

content shifting behind modal

When the scrollbar is removed, the content takes up that extra width, leading to text and content reflowing, and backgrounds repositioning.

In the past I've solved this in two ways: adding padding/margin on <html>, or setting the width of <html>.

These values have to be recalculated and updated when the window is resized, or as content is added/removed.

Modal Over Everything

So today as I was building a modal I got to this stage and thought about why the modal exists within the scrollable content. It should be fully separate, and on top of the scrollbar. This is possible by restructuring the document.

The modal has to be outside the scrollable content; it's added to the <body> and can't be any higher up the DOM, so the scrollable content will need to be a child of <body>.

What I like about this:

  1. no code to remove/add scrollbars
  2. no code to set width/margin to account for the scrollbar
  3. no recalculations when resized

It just works.


One drawback with this setup is that it's atypical. Any other code expecting overflow to be on <html> or <body> will need to be refactored. This and other issues likely wouldn't be hard to resolve.

I plan to test this solution further for browser and device compatibility, and hopefully it proves out.

Top comments (1)

melnik909 profile image
Stas Melnikov

Thank you!