Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] Prevent scrolling on html/body #273

Open
corysimmons opened this issue Dec 20, 2016 · 13 comments
Open

[feature request] Prevent scrolling on html/body #273

corysimmons opened this issue Dec 20, 2016 · 13 comments

Comments

@corysimmons
Copy link

When modals are expanded, it's nice if the html/body isn't able to scroll.

You can achieve this by applying overflow: hidden to both.

Need to be mindful that content can expand vertically further than screen so overflow-y: auto would need to be added to the lightbox container.

@marcandre
Copy link
Collaborator

What would be the impact on #77?

@corysimmons
Copy link
Author

corysimmons commented Dec 21, 2016

I don't think the html, body {overflow: hidden} styles would cascade to the <iframe> if it was on a different origin.

I'm too lazy to check if it'd affect it on same origin. If it did, maybe this would work:

html,
body {
  overflow: hidden; // disable for local viewport
}

html html {
  overflow: auto; // enable for child viewport
}

Bootstrap, and 99% of other modal frameworks do this. Locking the viewport is pretty standard with modals.

@michaelcoconnor
Copy link

I'm not fully understanding the comments here as I'm not very advanced. That said, I have an example for you of inappropriate scrolling of the underlying page when the user is scrolling in the lightbox. It's on this page. First make sure that your window height is not so huge that scrolling is not necessary to see the bottom of that page. Then, in the sticky footer, click on [Terms of Use].

The deal is that if you keep the cursor inside the Terms of Use box at all times and use the mouse scroll wheel to get to the bottom, all will go well, but... if you keep scrolling a bit more, as if to scroll an inch or more past the end of the box, the underlying page starts to scroll. This also happens in the other direction. In both cases the underlying page must of course not already be scrolled to the end in order for this to be observed.

The comments about overflow don't seem to me to be relevant to what I'm demonstrating, but I'm not utterly sure. Is this a Featherlight bug? Or is it me?

The box is no iframe but is loaded with ordinary HTML, via <a href="#" data-featherlight="url_to_django_script_that_returns_html">.

@marcandre
Copy link
Collaborator

After some consideration, I tend to agree with the request.

@corysimmons Is there a need to add overflow: hidden to the body in addition to the <html>?

@marcandre
Copy link
Collaborator

Also, the close button should probably not be scrolling. Is there a simple way to achieve that though?

@marcandre
Copy link
Collaborator

Latest version should not scroll globally.
Would still be nice to have the close box not scrolling either.

@michaelcoconnor
Copy link

I have just now installed 1.7.1 on the site to which I provided a link above, and I'm seeing the same scrolling behavior.

@jameswilson
Copy link

@marcandre regarding your statement:

Latest version should not scroll globally.

Can you explain what you mean by latest version? I'm still seeing a separate "scroll" branch where this was fixed but never merged to master for inclusion in a release. I just looked at 1.7.7 and it doesn't contain the code from the scroll branch:

https://github.com/noelboss/featherlight/compare/scroll

Were you waiting for a fix of the close box scrolling you mentioned above to work this into a release?

@marcandre
Copy link
Collaborator

Oh 😊, sorry, indeed the changes never made it to master.

1.7.8 released.

@jameswilson
Copy link

Mil Merci! @marcandre

jameswilson added a commit to BluesparkLabs/featherlight that referenced this issue Aug 14, 2017
@jameswilson
Copy link

I've done some cross-browser and device testing of this solution and found that it does not work on iOS, because mobile safari does not respect overflow: hidden on the html element as a way to prevent scrolling. The workaround requires also setting position: fixed on the body tag, and then a small piece of javascript to fix the scroll position in place and prevent that slinky top/bottom edge effect as you drag/scroll with your finger on touch devices.

Here is a workaround that can be used inside my application's script:

  $.featherlight.defaults.beforeOpen = function() {
    // Lock the scroll position in place on the body with 'position:fixed' and negative top margin.
    $(document.body).css({
      'top':  '-' + $(document.body).scrollTop() + 'px',
      'position': 'fixed',
      'width': '100%', // ensure page width unaffected by fixed position.
      'height': 'inherit' // note height of 100% on body breaks ios
    });
  };

  $.featherlight.defaults.afterClose = function() {
    // Unset the scroll position on the body.
    var top = Math.abs(parseInt($(document.body).css('top')));
    $(document.body).css({
      'top': '',  // Empty value removes the CSS rule from the inline style attribute.
      'position': '',
      'width': '',
      'height': ''
    });
    // Move viewport back to the original position which was lost when body was
    // locked with 'position: fixed'.
    window.scrollTo(0, top);
  }

I'll submit a PR momentarily containing this solution rewritten as something that will work generically.

Thanks.

@pandalion
Copy link

pandalion commented Feb 8, 2018

@marcandre is there any reason not to overwrite the close button position to fixed in our own css? This does the job with the close button for me, to avoid it scrolling out of view.

Edit - I see this wouldnt necessarily work if the modal isn't the size of the window.

@ganar
Copy link

ganar commented Mar 6, 2018

@jameswilson thanks a lot for this solution.

If you want the to work across browsers —chrome V 60+ does not work in the original— this small change will do the trick >

'top': '-' + window.scrollY + 'px',

instead of

'top': '-' + $(document.body).scrollTop() + 'px',

I tested the change in Safari, Chrome and Firefox

  $.featherlight.defaults.beforeOpen = function() {
    // Lock the scroll position in place on the body with 'position:fixed' and negative top margin.
    var topOriginal = Math.abs(parseInt($(document.body).css('top')));
    $(document.body).css({
      'top':  '-' + window.scrollY  + 'px',
      'position': 'fixed',
      'width': '100%', // ensure page width unaffected by fixed position.
      'height': 'inherit' // note height of 100% on body breaks ios
    });
  };

  $.featherlight.defaults.afterClose = function() {
    // Unset the scroll position on the body.
    var top = Math.abs(parseInt($(document.body).css('top')));
    $(document.body).css({
      'top': '',  // Empty value removes the CSS rule from the inline style attribute.
      'position': '',
      'width': '',
      'height': ''
    });
    // Move viewport back to the original position which was lost when body was
    // locked with 'position: fixed'.
    window.scrollTo(0, top);
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants