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?
Best Solution
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 andoverflow: hiddenis set, thusbodyis no longer scrollable.The overlay (created on-the-fly or already inside 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.The
divinside the overlay is instead just inposition: staticthen the vertical scrollbar you see is related to that element. As a result the content is scrollable but overlay remains fixed.When you close the zoom you hide the overlay (via
display: none) and then you could also entirely remove it via javascript (or just the content inside, it's up to you how to inject it).As a final step you have to also remove the
noscrollclass to thebody(so the overflow property returns to its initial value)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