twitter bootstrap 3 modal on mobile scroll issues

twitter bootstrap 3 modal on mobile scroll issues

I am currently using twitter bootstrap 3 modal on mobile. It works perfectly fine on desktop, however on mobile whenever I scroll it also scrolls the window behind the modal. How do I prevent this from happening?

Solutions/Answers:

Solution 1:

FOR BOOTSTRAP 3

I found a fix for this issue that seems to be good enough for my site.

CSS:

body.modal-open > .wrap {
  overflow: hidden;
  height: 100%;
}

.modal-content, 
.modal-dialog, 
.modal-body { 
  height: inherit; 
  min-height: 100%; 
}

.modal { 
  min-height: 100%; 
}

HTML:

<body>
  <div class="wrap">All non-modal content</div>
  <div class="modal"></div>
</body>

So in the case that a modal is open, all non-modal content is limited to the height of the viewport and overflow is hidden, which prevents the main site from being scrolled, while the modal can still be scrolled.


EDIT: This fix has some issues in Firefox.

Fix for my site was (FF only media query):

@-moz-document url-prefix() {
  .modal-body { height: auto; min-height: 100%; }
  .modal { height: auto; min-height: 100%; }
  .modal-dialog {
    width: 100%;
    height: 100%;
    min-height: 100%;
    padding: 0;
    margin: 0;
    top: 0;
    left: 0;
  }

  .modal-content {
    height: auto;
    min-height: 100%;
    border-radius: 0;
    border: 0px solid #000;
    margin: 0;
    padding: 0;
    top: 0;
    left: 0;
  }

}

Solution 2:

Yea this was super annoying when I came across this issue on my iphone 6s today.

Related:  Overriding bootstrap table-striped CSS

This still seems to be an issue, even with the latest bootstrap (3.3.6 at my moment).

CSS Quickfix Solution:

body.modal-open { position: fixed; }

“Note that this has the side-effect of “scrolling” to the top of the page while the modal is open.”

See more details about this solution here

Javascript/jQuery Solution:

A better solution would be to utilize bootstrap’s modal events. This solution integrates the quickfix method, but fixes the ‘top of page’ problem.
You can then alter the css as needed depending on the event.

In my code below, I set the current position of the window on the event show.bs.modal (this value is used to fix the ‘quickfix’ problem).

I then apply the css quick fix on the shown.bs.modal event. In other words, after the modal pops up.

Finally, when the modal is closed, I switch the body’s position to relative (can be set to static as well I believe) and scroll the window back to its original position.

// set current position
var cPosition = false;

$('.modal').on('show.bs.modal', function(){

    cPosition = $(window).scrollTop();
})
.on('shown.bs.modal', function(){

    $('body').css({
        position:'fixed'
    });

})
.on('hide.bs.modal', function(){

    $('body').css({
        position:'relative'
    });

    window.scrollTo(0, cPosition);

});    

Should be relatively simple to set up for anyone with some javascript experience.

Hopefully they will solve this issue in bootstrap 4, but until then, hope this answer helps out other people with similar problems.

Related:  Input widths on Bootstrap 3

Solution 3:

I have noticed that it only scrolls the background page when in the modal your scrolling and you hit the bottom of the modal, then if you try to keep scrolling down it scrolls the background page. Look to the right side overflow bar, it just visible when the modal is open (on Chrome-Android)

Seems like the effect is to scroll the modal to the extent of modal, then automatically scroll the background page even though the modal is still open.

Solution 4:

Interestingly enough, they address this in the docs without offering much in the way of a solution:

“Support for overflow: hidden on the <body> element is quite limited in iOS and Android. To that end, when you scroll past the top or bottom of a modal in either of those devices’ browsers, the <body> content will begin to scroll.”

http://getbootstrap.com/getting-started/#overflow-and-scrolling

Solution 5:

Hey guys so i think i found a fix for Bootstrap 3. This is working for me on iphone and android at the moment. Its a mash up of hours upon hours of searching, reading and testing. So if you see parts of your code in here credit goes to you lol.

@media only screen and (max-device-width:768px){

body.modal-open {
// block scroll for mobile;
// causes underlying page to jump to top;
// prevents scrolling on all screens
overflow: hidden;
position: fixed;
}
}

body.viewport-lg {
// block scroll for desktop;
// will not jump to top;
// will not prevent scroll on mobile
position: absolute; 
}

body {  
overflow-x: hidden;
overflow-y: scroll !important;
}

The reason the media specific is on there is on a desktop i was having issues with when the modal would open all content on the page would shift from centered to left. Looked like crap. So this targets up to tablet size devices where you would need to scroll. There is still a slight shift on mobile and tablet but its really not much. Let me know if this works for you guys. Hopefully this puts the nail in the coffin

Related:  How to check if bootstrap modal is open, so i can use jquery validate

Solution 6:

For Bootstrap 3

I found a solution for mobile devices (touch screen) with iscroll.js

in the content of the modal add:

 <div id="smartScroll"> Content of the modal </div>

To initialize on .js

var myScroll = new IScroll('#smartScroll', {
   mouseWheel: true,
   scrollbars: true,
   click: true
});

References