简体   繁体   中英

Setting overflow-y: hidden; causes the page to jump to the top in Firefox

I've got some javascript which handles opening modal popups on my website, and it also sets the overflow-y property on the <html> element to hidden . In Chrome and IE this works as expected - the scrollbar hides, and the page behind the modal popup remains in the same scroll position. When the popup is closed, overflow-y is set to scroll and the page is in the same state and position as before.

However in Firefox, as soon as overflow-y is changed to hidden the page scroll position jumps to the very top, and so when the popup is closed the view has changed for the user - not ideal.

The problem can be seen on this jsfiddle

Is there any solution for this behaviour?

Don't use overflow: hidden on html , only on body . I had the same problem but fixed it by removing html .

Instead :

$('body, html').css('overflow', 'hidden');

Do :

$('body').css('overflow', 'hidden');

I had the same issue after checking it in the inspector window, I noticed that in the reset CSS, HTML is set to

HTML {
    overflow-y: scroll;
}

you can fix this by setting it to

HTML {
    overflow-y: initial;
}

If you don't want to touch reset CSS or just comment it

plugin and code is absolutely fine

change modal position from absolute to fixed:

#mymodal {
    position: fixed
 }

There are lots of bugs in the different browsers and the functionality is all over the place so be careful modifying styles on body and html tags.

To solve this issue i had to wrap the body's content into its own element and apply the scrolling restriction on it:

var $content = $('<div/>').append($body.contents()).appendTo($body);
$content.css('overflow-y', 'hidden');

This is the only way i've been able to get this working consistently across different browsers and devices.

I just encountered this problem. My fix was

/**
 * Store the scroll top position as applying overflow:hidden to the body makes it jump to 0
 * @type int
 */
var scrollTop;

$(selecor).unbind('click.openmenu').on('click.openmenu', function (e) {
    // Stuff...
    scrollTop = $('body').scrollTop() || $('html').scrollTop();
    $('body,html').css({overflow: 'hidden'});
});

$(selector).unbind('click.closemenu').on('click.closemenu', function (e) {
    // Stuff
    $('body,html').css({overflow: 'initial'}).scrollTop(scrollTop);
});

This however doesn't solve the problem of what happens if a user resize the viewport.

Edit: I just saw your code and you used a link with href="#". That is most likely the cause. I'd suggest removing the href property or use a button for it.

You should consider that this might not be caused by the css itself. In my case I opened my popup with a link: <a href="#">open popup</a> So what actually caused the jump to the top was the "#" in the href property of the link.

I removed it and added a noscroll class to my html and body tag:

.noscroll {
    overflow: hidden;
}

Keeping the body height 100% from the beginning solved the problem for me.

body{
   height:100vh;
   overflow:auto;
}
body.with-modal{
   overflow:hidden;
}

Use body tag instead of html.

JS Fiddle :- http://jsfiddle.net/SBLgJ/6/

JS Change:-

$(document).ready(function() {
    $('#middle a').on('click', function(e) {
        e.preventDefault();
        $('body').css('overflow-y', 'hidden');  
    });
});

CSS Change:-

body {
    overflow-y:scroll;
}

There is a reported issue for such behavior. ( https://github.com/necolas/normalize.css/issues/71 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM