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.
The most basic modal is 2
- an overlay
position: fixed;in the
- 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.
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
<body>, removing the scrollbar entirely. This also works if the modal content is scrollable.
Removing the scrollbar fixes one problem, but introduces another: the underlying content shifts position.
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
<html>, or setting the
These values have to be recalculated and updated when the
window is resized, or as content is added/removed.
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
What I like about this:
- no code to remove/add scrollbars
- no code to set width/margin to account for the scrollbar
- 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
<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.