How to disable page scrolling without hiding the scrollbars



This is useful when showing an overlay dialog box, in order to prevent the content underneath to scroll.

While adding a simple class no-scroll to the body:


body.no-scroll {overflow-y:hidden;}

gives a simple and easy solution, there is still one problem left: when the scrollbar disappears, the available horizontal width expands, so most of the time there is a visible jump in the horizontal offset of the page layout.

While it is not possible to actually “disable” the scrollbar without hiding it, an effective solution is to calculate the scrollbar width – which is different for every browser – and add it as margin-right property to the body tag.

$(document).ready(function() {
     //called only once

    function togglePageScroll(enable) {
        var b = $('body');
        if (enable) {
            b.removeClass('no-scroll').css('margin-right', '0px');
        } else {
            var normalw = 0;
            var scrollw = 0;
            if (b.prop("scrollHeight") > $(window).height()) {
                //The scrollbar is visible
                var scrollbarW = scrollbarWidth();
                b.css('margin-right', scrollbarW + 'px');
            }
            b.addClass('no-scroll');
        }
        return;
    }
});

This allows to easily enable/disable the page scroll, when opening/closing the overlay box.


//Shows the overlay:
togglePageScroll(false);
$('#overlay').fadeIn();

//Hides the overlay and restore the page scroll:
togglePageScroll(false);
$('#overlay').fadeOut();

Finding the scrollbar width

A simple function that returns the scrollbar width was posted on jdsharp.us: it basically adds a temporary div to the page, and finds its inner width when the scrollbar is visible and when it’s not. The problem is that the innerWidth() function returns the overall width in Chrome (41.0.2272.104).

After several attempts, I have found an even simpler solution that appears to be working on the latest versions of Firefox, Chrome, Safari and Explorer.

function scrollbarWidth() { 
 return window.innerWidth-$('html').width();
}

Leave a comment