3

Using A Transient CSS Stylesheet To Remove Scrolling On Body While Modal Is Open

 1 year ago
source link: https://www.bennadel.com/blog/4442-using-a-transient-css-stylesheet-to-remove-scrolling-on-body-while-modal-is-open.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Using A Transient CSS Stylesheet To Remove Scrolling On Body While Modal Is Open

By Ben Nadel on April 7, 2023

Yesterday, I demonstrated that removing a CSS stylesheet removes its affect on the document. This feature of the DOM (Document Object Model) allows us to apply temporary styles that can be easily toggled on-and-off. At work, I use this technique to temporarily disable scrolling on the body while a modal window is open. This is particularly helpful because CSS properties like overscroll-behavior don't work on non-scrolling elements.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

By default, the browser's user-agent applies an implicit "overflow" behavior on the document. This way, when you have a lot of content to deliver, scrollbars render on the side of the window and allow you to move beyond the current viewport. To disable scrolling on the window / body, we can provide our own "overflow" CSS property block:

By using the !important flag, these styles should override any existing height and overflow styles, hiding the scrollbar on the window. I include height here because I sometimes see a strange "jump to top" behavior in certain browsers when scrolling is disabled on a body that has an explicitly-defined height property.

Now that we have an understanding of how we can disable scrolling on the body, let's combine this set of properties with our transient stylesheet technique in order to only disable scrolling when a modal window is open.

In the following demo, I'm going to take the above <style> tag and dynamically inject it into the <head> tag when our modal window is open. Then, when the modal window is closed, I'm going to remove the <style> tag:

As you can see, when the modal window is opened, I am dynamically generating the <style> block and applying it so the DOM using head.prepend(). Then, when closing the modal window, I query for the first <style> element in the <head> and .remove() it. And, when we run this in the browser, we get the following output:

When the modal window is open, the scrollbars disappear on the body (while the underlying page retains its current scroll offset). Then, when the modal window is closed, the scrollbars reappear on the body.

As you can see, when the modal window is opened, the scrollbars on the window / body disappear. And, what's more, the underlying document retains its current scroll offset. Then, when the modal window is closed - and the transient <style> tag is removed from the document - the window's scrollbars reappear (again at the previous scroll offset), and I'm free to scroll the document.

Why Not Just Apply a CSS Class to the Document?

You might wonder why I bother with dynamically generating and injecting a <style> tag - why not just apply a CSS class to the document? It's a good question. And, on its face, it does seem like a simple CSS class would accomplish the same thing. But, the benefit that <style> tags have is that they can be stacked. Meaning, I can apply multiple, duplicate <style> tags to the document. And, the effect of the style tags will continue to apply until all stacked stylesheets are removed.

Now, imagine that you have to build a layout that can render multiple modals at a time. Or, maybe one modal and one alert interface. If you attempted to disable scrolling with a CSS class, you might end up adding the same CSS class twice (once for the modal, once for the alert). But, since CSS classes are unique, it only shows up once in the DOM. Then, when you close the alert, and remove the relevant CSS class, you end up removing it for both the modal and the alert, thereby re-enabling scrolling prematurely.

By injecting <style> tags, you have to "remove" as many as you "inject". This makes the logic more flexible and resilient to complex layouts.

Pro Tip: Developers Should ALWAYS Have Scrollbars Enabled

Unfortunately, when Apple started hiding scrollbars by default, it ruined a whole generation of web developers who forget that not all operating systems work this way. This has lead to an endemic of janky scroll containers (See: Rant). Please, do the world a favor and make sure that your scrollbars are set to always show so that you can foster better empathy with your users.

Want to use code from this post? Check out the license.

Enjoyed This Post? ❤️ Share the Love With Your Friends! ❤️

Tweet This Fascinating post by @BenNadel - Using A Transient CSS Stylesheet To Remove Scrolling On Body While Modal Is Open https://www.bennadel.com/go/4442

Reader Comments

Hey Ben, you thought about using the native DIALOG element for models? Support is good now and been using them instead of DIVs. 'Feels' like the right element to use.

@Dave,

Great minds think alike. I actually have the Mozilla Docs for <dialog> open in another tab. I've never used it before; and, at work, I've sort of had to support IE11 for the longest time (not even sure what our Support docs say at this point). But, I am keen to start trying out these newer things.

Yeah IE11 and earlier versions of Safari I think are a problem.

If the feature is critical, and you need to support them, would be an issue

Most of the features we use them for aren't mission critical so we just check to see if dialog is supported, if so, add class to the feature so it shows.

The DIALOG has been really easy to style and is consistent across browsers. Definitely give it a try.

Been trying to use more and more of the native stuff lately. HTML and CSS have come a long way. CSS especially.

@Dave,

Totally agree -- I feel like there's a whole host of elements and CSS properties that I haven't been able to use due to IE11 restrictions. I am excited to get "back out there" and see what's available. The dialog is one; I know people have been making a lot of fuss about the summary/detail stuff that GitHub has popularized. Honestly, I could probably due with some sort of course for native HTML.

Post A Comment — ❤️ I'd Love To Hear From You! ❤️

Name:

Email:

Website:

Comment:
NEW: Some basic markdown formatting is now supported: bold, italic, blockquotes, lists, fenced code-blocks. Read more about markdown syntax »
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Subscribe to comments.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK