carl
carl

Reputation: 4436

smooth scroll does not work with overflow-y

I am trying to use a smooth scroll and adopted an example I found online. Here is a fiddle with my code

https://jsfiddle.net/4DcNH/144/

I have special conditions set to html and body (basically to offset the page context by 50px from the top to avoid the navbar). Therefore the smooth scroll does not work. Does anybody know a solution to this? thanks carl

$(document).ready(function() {
$('a[rel="relativeanchor"]').click(function(){
    $('html, body').animate({
        scrollTop: $( $.attr(this, 'href') ).offset().top
    }, 2000);
    return false;
}); 
});

Upvotes: 0

Views: 866

Answers (2)

Peter Wooley
Peter Wooley

Reputation: 18

The issue appears to be related to differences in how Chrome scrolls the <body> with height:100%. A discussion of the issue is here: Body set to overflow-y:hidden but page is still scrollable in Chrome

A workable solution is to wrap the scrolling content in <div class="content"> and disable scrolling on <body>.

Here's a JSFiddle to demonstrate the updated behavior: https://jsfiddle.net/f1zv1c5k/5/

To get the scroll to stop at the appropriate point, you need to subtract the vertical offset applied to the <html> tag (using $el.prop('offsetTop') recommended by @vol7ron) when scrolling. Your smooth scroll function would look like this:

$('a[rel="relativeanchor"]').click(function(){
    var $el = $($(this).attr('href'));
    $('.content').animate({
        scrollTop: $el.prop('offsetTop')
    }, 2000);
    return false;
}); 

Upvotes: 0

vol7ron
vol7ron

Reputation: 42179

Is this what you're after?

$(document).ready(function () {
    if(!/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())){
        $('html').css({'overflow-x':'auto','overflow-y':'hidden'});
    }
    $('a[rel="relativeanchor"]').click(function () {
        var $el = $($(this).attr('href'));
        $('html, body').stop().animate({
            scrollTop: $el.prop('offsetTop')
        }, 2000);
        return false;
    });
});

JSFiddle

Updates were needed in the CSS. The html overflows were removed for chrome, because otherwise, this would not work in Chrome. However, the overflows are needed for Firefox, so they are done by setting it dynamically in the JavaScript (set if not chrome).

If you want to maintain an offset, subtract it from the calculated offset. Given the above, $el.prop('offsetTop') - 50 adds 50px above.

Upvotes: 1

Related Questions