55

is it possible to disable scrolling in browser (just for browser's scrollbars) while a jQuery UI modal dialog is open.

Note: I do want scrolling to be enabled inside the dialog

3
  • So how did you enable the scroll inside your dialog using correct answer?
    – Feanor
    Commented Sep 25, 2014 at 14:01
  • @Feanor atm I'm setting css position:fixed for the dialog div, so even though the browser scrolls the dialog stays fixed, and inside the dialog the scroll works with default css (overflow: auto)
    – Omu
    Commented Sep 26, 2014 at 7:57
  • JSBin reference for css overflow jsbin.com/yicidecodu/1/edit?html,css,output Commented Nov 21, 2014 at 11:16

16 Answers 16

77
$(formObject).dialog({
 create: function(event, ui) {
  $("body").css({ overflow: 'hidden' })
 },
 beforeClose: function(event, ui) {
  $("body").css({ overflow: 'inherit' })
 }
});

Or as I allude to in the comment below:

var dialogActiveClassName="dialog-active";
var dialogContainerSelector="body";

$(formObject).dialog({
 create: function(event, ui) {
   $(dialogContainerSelector).addClass(dialogActiveClassName);
 },
 beforeClose: function(event, ui) {
   $(dialogContainerSelector).removeClass(dialogActiveClassName);
 }
});

But actually to be honest, you should ensure that creating a dialog bubbles an event up to your window object where you'd be watching for said events, roughly something like this pseudo:

var dialogActiveClassName="dialog-active";
var dialogContainerSelector="body";
$(window).on("event:dialog-opened", function(){
    $(dialogContainerSelector).addClass(dialogActiveClassName);
});
$(window).on("event:dialog-closed", function(){
    $(dialogContainerSelector).removeClass(dialogActiveClassName);
});
7
  • 3
    This only hides scroll bars, it doesn't prevent scrolling Commented Dec 7, 2011 at 15:09
  • 10
    Also worked for me. If you want to open the dialog later (not on page load) then bind the scrollbar hiding to the 'open' event instead of 'create'.
    – Germstorm
    Commented Nov 15, 2012 at 9:48
  • 2
    At first, it would not work for my project while using IE8. However, I got it to work by changing the above selector to $("html, body") so the style would be applied to both the body element and the HTML element. For some reason this made it start working for me! Just mentioning this here in case anyone else runs into this problem.... hopefully it will save someone time. The only problem I have with this overall solution is when the Y-axis scroll bar disappears, it creates a slight horizontal screen jitter. (When the jquery dialog opens and when it closes) Commented Mar 19, 2013 at 18:38
  • 1
    actually the "Best Practice"(tm) way to deal with this is to toggle a class name on what ever container object wraps around your dialog element.
    – airtonix
    Commented Aug 6, 2013 at 6:11
  • 1
    I would recommend putting the function to prevent scroll on the open event instead of the create event. For example, if you have a button that shows the modal dialog, the body won't be able to scroll if you have already created the dialog, even if it's not showing.
    – Mike
    Commented Jan 23, 2014 at 0:12
47

I needed to do exactly the same thing, do it simply by adding a class to the body:

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

Add the class then remove when you want to re-enable scrolling, tested in IE, FF, Safari and Chrome.

$('body').addClass('stop-scrolling')
7
  • 4
    This really should be the answer!
    – Nate
    Commented Sep 13, 2013 at 19:11
  • /golf clap.. ::single_nod:: Commented Jun 26, 2014 at 19:05
  • Genial! You can put on dialog....open:function () { $('body').addClass('stop-scrolling');}, beforeClose:function (){$('body').removeClass('stop-scrolling');}.....
    – Adrian P.
    Commented Oct 17, 2014 at 14:30
  • Best answer, simply clever :-) Commented Nov 7, 2014 at 14:12
  • This is okay for mouse scroll, but you can still scroll with keyboard buttons with this.
    – TheCarver
    Commented Mar 15, 2015 at 15:35
28

JS Bin reference for CSS overflow

Simply Add

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

to your function that shows the modal.

And

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

to your function that closes the modal.

3
  • 2
    I cant have enough appreciation for a simple solution. Thanks! Commented Jul 26, 2015 at 20:39
  • the best solution! Commented Apr 1, 2017 at 2:55
  • For those who use primefaces and want to prevent body of the website to scroll while modal dialog is shown, just put these two into the onHide and onShow attributes of p:dialog e.g. onHide="$('body').css('overflow','scroll');" onShow="$('body').css('overflow','hidden');"
    – hocikto
    Commented Feb 22, 2018 at 13:12
7

Here is the best that I could come up with to solve this issue (I had the same problem) using the functions referenced in the answer by JasCav above (these functions):

dialogClass: 'dialog_fixed',
create: function(event, ui) {
    disable_scroll(); // disable while dialog is visible
    $('#dialog_form').hover(
        function() { enable_scroll(); }, // mouse over dialog
        function() { disable_scroll(); } // mouse not over dialog
    );
},
beforeClose: function(event, ui) {
    enable_scroll(); // re-enable when dialog is closed
},

the css is:

.dialog_fixed { position:fixed !important; }

and it just keeps the dialog fixed on the page, which maybe we don't need anymore.

This allows mouse scrolling while the mouse is over the dialog, but not when it is outside the dialog. Unfortunately it will still scroll the main page when the mouse is over the dialog and you scroll past the end of the content inside the dialog (in IE right away, in Safari and Firefox after a short delay). I would love to know how to fix this.

I tested this in Safari 5.1.5, Firefox 12, and IE 9.

5

Stops scrolling, adjusts dialog position and returns user to part of page they were viewing after they close the dialog

$('<div/>').dialog({
    open : function(event, ui) { 
        $('html').attr('data-scrollTop', $(document).scrollTop()).css('overflow', 'hidden');
        $(this).dialog('option','position',{ my: 'center', at: 'center', of: window });
    },
    close : function(event, ui) { 
        var scrollTop = $('html').css('overflow', 'auto').attr('data-scrollTop') || 0;
        if( scrollTop ) $('html').scrollTop( scrollTop ).attr('data-scrollTop','');
    }
});
1
  • This is the functionality that's expected when you want to stop a page from scrolling when the dialog is opened. If you're hovering over something when the dialog opens and want to retain the hover state, best way is to use add/remove class for the styles.
    – user1978550
    Commented Feb 3, 2016 at 5:07
4

You can't disable scrolling completely, but you can stop scrolling with the mouse wheel and the buttons that typically perform scrolling.

Take a look at this answer to understand how that is done. You could call these functions on the create event and return everything to normal, on close.

2
  • 19
    This is a nice solution, but it disables scrolling in the dialog as well, but if I understand the question correctly, we want the scrolling to work in the dialog, just not anywhere else. Commented May 2, 2012 at 19:03
  • @CraigNakamoto, I think you can attach the eventListener to the dialog after then. So the scroll will be disabled in document level, but the dialog still have a event listener for scroll. It will be something like $(document).('on', '.dialog', function(){ /*scroll code*/ });
    – lhrec_106
    Commented May 13, 2016 at 2:01
3

Just a modification on an answer posted above by hallodom

$('body, html').addClass('stop-scrolling')

browser scrolling wasn't disabled until I added html.

.stop-scrolling {
  overflow: hidden;
}

by removing height: 100%, the bump-to-top effect was removed.

Tested on Chrome, Firefox and Safari.

2

Old post but the way I did it was:

open: function(event, ui) {                
     $('html').css('overflow', 'hidden');
     $('.ui-widget-overlay').width($(".ui-widget-overlay").width() + 18);
     },
close: function(event, ui) {
     $('html').css('overflow', 'hidden');
}

This seems to work quite nicely

2

Searched for a long long time. Finally the follow link saves me. Hope it's helpful to others.

It uses a container for the main body. The scrolling in dialog won't affect the background container.

http://coding.abel.nu/2013/02/prevent-page-behind-jquery-ui-dialog-from-scrolling/

2

Create this css class:

.stop-scrolling {
    overflow:hidden;
    height: 100%;
    left: 0;
    -webkit-overflow-scrolling: touch;
    position: fixed;
    top: 0;
    width: 100%;
}

Then add this to your dialog init:

$("#foo").dialog({
    open: function () {
        $('body').addClass('stop-scrolling');
    },
    close: function () {
        $('body').removeClass('stop-scrolling');
    },
    // other options
});

If you are already using open: and close: to call other functions, just add the addClass and removeClass lines in the appropriate place.

2
$(settings.dialogContentselector).dialog({
        autoOpen: false,
        modal: true,
        open: function( event, ui ) {
            $("html").css({ overflow: 'hidden' });
            $("body").css({ overflow: 'hidden' });
        },
        beforeClose: function( event, ui ) {
            $("html").css({ overflow: 'auto' });
            $("body").css({ overflow: 'auto' });
        }
    });
1

try this one. it being used by http://jqueryui.com itself

html { overflow-y: scroll; }

1

create: event Makes scrollbars disappear when page loading for first time I change it with open: and working now like a charm

0

A better solution avoiding body jumps to top when popup is closed:

$(document).ready(function(){
  var targetNodes         = $(".cg-popup");
  var MutationObserver    = window.MutationObserver || window.WebKitMutationObserver;
  var myObserver          = new MutationObserver (mutationHandler);
  var obsConfig           = { attributes : true, attributeFilter : ['style'] };
  // ADD A TARGET NODE TO THE OBESERVER. CAN ONLY ADD ONE NODE AT TIME
  targetNodes.each ( function () {
      myObserver.observe (this, obsConfig);
  } );
  function mutationHandler (mutationRecords) {
    var activate_scroll = true;
    $(".cg-popup").each(function( index ) {
      if($(this).css("display") != "none"){
        $('html, body').css({'overflow-y': 'hidden', 'height': '100%'});
        activate_scroll = false;
        return;
      }
    });
    if(activate_scroll){
      $('html, body').css({'overflow-y': 'auto', 'height': 'auto'});
    }
  }
});
-1

This issue is fixed, Solution: Just open your bootstap.css and change as below

body.modal-open,
.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
margin-right: 15px;
}

to

body.modal-open,
.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
/margin-right: 15px;/
}

Please view the below youtube video only less than 3min your issue will fix... https://www.youtube.com/watch?v=kX7wPNMob_E

-3

It is because you have to add modal: true in your code; this prevent user from interacting with background.

1
  • 1
    you can't interact with the background but you still can scroll the page using the scrollbars or the mouse wheel Commented Jan 30, 2013 at 8:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.