How to prevent background scrolling when Bootstrap 3 modal open on mobile platforms? On desktop browsers the background is prevented from scrolling and works as it should.<
The above answers did not help so what I did was:
.modal {
-webkit-overflow-scrolling: touch;
}
My particular problem was when I increased the modal size after loading.
It's a known iOS issue, see here. Since it does not break anything else the above solution was enough for my needs.
The chosen solution works, however they also snap the background to the top scrolling position. I extended the code above to fix that 'jump'.
//Set 2 global variables
var scrollTopPosition = 0;
var lastKnownScrollTopPosition = 0;
//when the document loads
$(document).ready(function(){
//this only runs on the right platform -- this step is not necessary, it should work on all platforms
if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
//There is some css below that applies here
$('body').addClass('platform-ios');
//As you scroll, record the scrolltop position in global variable
$(window).scroll(function () {
scrollTopPosition = $(document).scrollTop();
});
//when the modal displays, set the top of the (now fixed position) body to force it to the stay in the same place
$('.modal').on('show.bs.modal', function () {
//scroll position is position, but top is negative
$('body').css('top', (scrollTopPosition * -1));
//save this number for later
lastKnownScrollTopPosition = scrollTopPosition;
});
//on modal hide
$('.modal').on('hidden.bs.modal', function () {
//force scroll the body back down to the right spot (you cannot just use scrollTopPosition, because it gets set to zero when the position of the body is changed by bootstrap
$('body').scrollTop(lastKnownScrollTopPosition);
});
}
});
The css is pretty simple:
// You probably already have this, but just in case you don't
body.modal-open {
overflow: hidden;
width: 100%;
height: 100%;
}
//only on this platform does it need to be fixed as well
body.platform-ios.modal-open {
position: fixed;
}
I've found a simple javascript/jquery solution which utilizes the bootstrap modal events.
My solution also fixes the position:fixed
problem where it scrolls the background page all the way back to the top instead of staying in place when modal window is opened/closed.
See details here
Using position:fixed
has the side effect of scrolling the body to the top.
If you do not your body to scroll to the top, DO NOTE use position:fixed
. Just disable touchmove on the body if the modal is open.
Note: The modal itself is still able to scroll on touch (if larger than the screen).
CSS:
body.modal-open {
overflow: hidden;
width: 100%;
/* NO position:fixed here*/
}
JS:
$('.modal').on('show.bs.modal', function (ev) { // prevent body from scrolling when modal opens
$('body').bind('touchmove', function(e){
if (!$(e.target).parents().hasClass( '.modal' )){ //only prevent touch move if it is not the modal
e.preventDefault()
}
})
})
$('.modal').on('hide.bs.modal', function (e) { //unbind the touchmove restrictions from body when modal closes
$('body').unbind('touchmove');
})
EDIT: Note, for very small modals, you might have to add the following line to your CSS:
.modal-dialog{
height: 100%;
}
See here: https://github.com/twbs/bootstrap/issues/7501
So try:
$('body').css('overflow','hidden');
$('body').css('position','fixed');
V3.0.0. should have fixed this issue. Do you use the latest version? If so post an issue on https://github.com/twbs/bootstrap/
I tried the accepted answer which prevented the body from scrolling but had the issue of scrolling to the top. This should solve both issues.
As a side note, it appears overflow:hidden doesn't work on body for iOS Safari only as iOS Chrome works fine.
var scrollPos = 0;
$('.modal')
.on('show.bs.modal', function (){
scrollPos = $('body').scrollTop();
$('body').css({
overflow: 'hidden',
position: 'fixed',
top : -scrollPos
});
})
.on('hide.bs.modal', function (){
$('body').css({
overflow: '',
position: '',
top: ''
}).scrollTop(scrollPos);
});