FloatingRock
FloatingRock

Reputation: 7065

Prevent dialog on mobile screen from scrolling the body

I'm displaying a dialog on a mobile screen that's longer than the size of the screen (so it scrolls).

Here's the problem: When you scroll past the bottom of the dialog (I happen to be using Bootstrap 3), I expect it to just stop. Instead, it starts scrolling the underlying body. I've tried everything that's been suggested in this recommended solution, and it still doesn't freaking work!

Here's a live demo of the issue on JSbin, for your viewing pleasure

http://jsbin.com/EdAhAsU/1/

Note: To reproduce the issue, access it using a mobile - any mobile - and attempt to scroll past the end of the dialog. Tried it on Android, and iPhone - doesn't work for either.

Thanks!

Upvotes: 2

Views: 16002

Answers (8)

Ollie Williams
Ollie Williams

Reputation: 2528

The easiest option is to use the overscroll-behavior CSS property on the popup.

.modal {
overscroll-behavior: contain;
}

This property was added to CSS specifically for this use case.

Upvotes: 3

Sven Finger
Sven Finger

Reputation: 543

Try this:

body {
    left: 0;
    -webkit-overflow-scrolling: touch;
    position: fixed;
    top: 0;
    width: 100%;
}

Works for me (see http://jsbin.com/aXoMaGo/2) in Safari/Chrome on iOS 7 and also gives the Modal a sexy bounce-effect.


Final solution that works (even when the dialog is dismissed): https://jsbin.com/aXoMaGo/6 . The only downside to this is that it scrolls to the top of the page each time the modal is dismissed.

Upvotes: 12

Judson Terrell
Judson Terrell

Reputation: 4306

This is the best solution I have come up with. You call prevent scroll on dialog open, then enable scroll on dialog close.

var lastScrollPos = 0;
preventScoll = function () {

    lastScrollPos = $('body').scrollTop();
    $('body').css('overflow', 'hidden');
    $('body').css('position', 'fixed');

}
enableScroll = function () {

    $('body').css('position', 'relative');
    $('body').css('overflow', 'auto');
    window.scrollTo(0, lastScrollPos);

}

Upvotes: 0

AliShafiee
AliShafiee

Reputation: 11

and this is my modal Html Code

<div class="modal fade" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" tabindex="-1" aria-describedby="ContentLoader">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
            <h4 class="modal-title">Topic title</h4>
          </div>
          <div class="modal-body">
              <!-- some content -->
          </div>
          <div class="modal-footer">
              <!-- footer -->
          </div>
        </div>
      </div>
    </div>

Upvotes: 0

AliShafiee
AliShafiee

Reputation: 11

I have same problem !I spend one day to fix this but ....

the only things that I write and work for me is this code i hope it work for ya !

if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
        $('.modal').on('show.bs.modal', function() {
                    var scrollNo=$(window).scrollTop();
                    $('.modal-open').css('position', 'fixed');
                  });
        $('.modal').on('hide.bs.modal', function() {
                    $('body').css('position', '');
                    $(window).scrollTop(scrollNo);  
                  });
    }

Upvotes: 1

Anobik
Anobik

Reputation: 4899

For all those Since I am not stisfied with the Answer it does not work on my note 8 . the screen actually freezes .

Here's the hack i created can be buggy but solves the major issue :)

js bin

Any clarifications are welcomed :)

Upvotes: 1

nloko
nloko

Reputation: 696

One issue is that your event names are off for Bootstrap 3. Another is that mobile, webkit-based browsers don't seem to obey overflow: hidden on the <body>. Try this:

$(function(){
  $('#myModal').modal().on('shown.bs.modal', function(){
    $('body').css({
      position: 'fixed'
    });
  }).on('hidden.bs.modal', function(){
    $('body').css({
      position: ''
    });
  });
});

Upvotes: 2

am80l
am80l

Reputation: 1531

I had a similar issue. Typically overflow:hidden accomplishes this on desktop. For mobile you'll also need to apply position fixed. So, when your dialog is active, add a ".noscroll" class to the body:

body.noscroll{
overflow:hidden;
position:fixed;
}

Upvotes: 2

Related Questions