Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent body scrollbar and shifting when twitter bootstrap modal dialog is loaded?

When I open the twitter bootstrap modal dialog, the backdrop causes a scrollbar and shift the content.

To avoid the scrollbar I use this css:

.modal {     overflow: hidden; } 

But I can not avoid the shift.

regards, Marko

I am using Bootstrap Version 3

like image 950
Marko Avatar asked Oct 10 '13 06:10

Marko


People also ask

How do you prevent body scrolling while modal is open?

Approach: A simple solution to this problem is to set the value of the “overflow” property of the body element to “hidden” whenever the modal is opened, which disables the scroll on the selected element.

How do I keep my bootstrap modal from closing when I click outside?

When the Button is clicked, the HTML DIV is referenced using jQuery and its modal function is called along with properties data-backdrop: "static" and data-keyboard: false which disables the closing of the Bootstrap Modal Popup when clicked outside.

How do I make my modal body scrollable?

Bootstrap 4.3 added new built-in scroll feature to modals. This makes only the modal-body content scroll if the size of the content would otherwise make the page scroll. To use it, just add the class modal-dialog-scrollable to the same div that has the modal-dialog class.

What is modal dialog in bootstrap?

Modals are built with HTML, CSS, and JavaScript. They're positioned over everything else in the document and remove scroll from the <body> so that modal content scrolls instead. Clicking on the modal “backdrop” will automatically close the modal. Bootstrap only supports one modal window at a time.


1 Answers

Marko,

I just had the same problem. It appears that Bootstrap 3.0.0 adds a class to <body>, modal-open, when the modal first shows. This class adds margin-right: 15px to the body to account for a scrollbar, which is there on longer pages. This is great, except for shorter pages when a scrollbar isn't on the body. In the no scrollbar case, the margin-right causes the body to shift left on modal open.

I was able to solve this by adding some short Javascript and a little CSS:

CSS:

/* override bootstrap 3 class to remove scrollbar from modal backdrop    when not necessary */ .modal {   overflow-y: auto; } /* custom class to override .modal-open */ .modal-noscrollbar {     margin-right: 0 !important; } 

JS:

(function($) {  $(document)     .on( 'hidden.bs.modal', '.modal', function() {         $(document.body).removeClass( 'modal-noscrollbar' );     })     .on( 'show.bs.modal', '.modal', function() {         // Bootstrap adds margin-right: 15px to the body to account for a         // scrollbar, but this causes a "shift" when the document isn't tall         // enough to need a scrollbar; therefore, we disable the margin-right         // when it isn't needed.         if ( $(window).height() >= $(document).height() ) {             $(document.body).addClass( 'modal-noscrollbar' );         }     });  })(window.jQuery); 

These combined permit the margin-right scrollbar fix to work for long pages, yet is disabled for shorter pages (when document height <= window height). I hope this helps!


Bootstrap 3.0.1+ (tested up to 3.1.1) is a different story. Try the following:

CSS:

/* override bootstrap 3 class to remove scrollbar from modal backdrop    when not necessary */ .modal {   overflow-y: auto; } /* custom class to add space for scrollbar */ .modal-scrollbar {     margin-right: 15px; } 

JS:

(function($) {  $(document)     .on( 'hidden.bs.modal', '.modal', function() {         $(document.body).removeClass( 'modal-scrollbar' );     })     .on( 'show.bs.modal', '.modal', function() {         // Bootstrap's .modal-open class hides any scrollbar on the body,         // so if there IS a scrollbar on the body at modal open time, then         // add a right margin to take its place.         if ( $(window).height() < $(document).height() ) {             $(document.body).addClass( 'modal-scrollbar' );         }     });  })(window.jQuery); 

EDIT:

In light of Mac eliminating scrollbars from inhabiting window render width, here's a more portable solution (3.0.1+) if you don't mind some feature detection. Reference: http://davidwalsh.name/detect-scrollbar-width

CSS:

.scrollbar-measure {     height: 100px;     overflow: scroll;     position: absolute;     top: -9999px; } 

JS:

window.jQuery(function() {   // detect browser scroll bar width   var scrollDiv = $('<div class="scrollbar-measure"></div>')         .appendTo(document.body)[0],       scrollBarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;    $(document)     .on('hidden.bs.modal', '.modal', function(evt) {       // use margin-right 0 for IE8       $(document.body).css('margin-right', '');     })     .on('show.bs.modal', '.modal', function() {       // When modal is shown, scrollbar on body disappears.  In order not       // to experience a "shifting" effect, replace the scrollbar width       // with a right-margin on the body.       if ($(window).height() < $(document).height()) {         $(document.body).css('margin-right', scrollBarWidth + 'px');       }     }); }); 
like image 166
ianmstew Avatar answered Oct 11 '22 13:10

ianmstew