I’ve been searching for a “lightbox” type solution that allows this but haven’t found one yet (please, suggest if you know of any).
The behavior I’m trying to recreate is just like what you’d see at Pinterest when clicking on an image. The overlay is scrollable (as in the whole overlay moves up like a page on top of a page) but the body behind the overlay is fixed.
I attempted to create this with just CSS (i.e. a div overlay on top of the whole page and body with overflow: hidden), but it doesn’t prevent div from being scrollable.
How to keep the body/page from scrolling but keep scrolling inside the fullscreen container?
Theory
Looking at current implementation of the pinterest site (it might change in the future), when you open the overlay, a
noscrollclass is applied to thebodyelement (settingoverflow: hidden) making thebodyno longer scrollable.The overlay created on-the-fly or already injected in the page and made visible via
display: block— it makes no difference – hasposition : fixedandoverflow-y: scroll, withtop,left,rightandbottomproperties set to0: this style makes the overlay fill the whole viewport (but now we are in 2022, so you may useinset: 0instead).The
divinside the overlay is inposition: staticso the vertical scrollbar is related to that element. This is resulting in a scrollable but fixed overlay.When you close the overlay, you have to hide it (using
display: none) and you could even remove the node via javascript (or just the content inside, it’s up to you but also depends on the nature of the content).The final step is to also remove the
noscrollclass applied to thebody(so theoverflowproperty gets back to the value it had previously)Code
(it works by changing the
aria-hiddenattribute of the overlay in order to show and hide it and to increase its accessibility).Markup
(open button)
(overlay and close button)
CSS
Javascript (vanilla-JS)
Finally, here’s another example in which the overlay opens with a fade-in effect by a CSS
transitionapplied to theopacityproperty. Also apadding-rightis applied to avoid a reflow on the underlying text when the scrollbar disappears.CSS