2

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!

Community
  • 1
  • 1
FloatingRock
  • 6,741
  • 6
  • 42
  • 75
  • In the default browser on my HTC One, the problem occours. But not in Google Chrome on the phone. – DannyThunder Sep 24 '13 at 10:55
  • @DannyThunder seems to be the exception. I tried it on Chrome on iOS7 on my iPhone 4S and i had the problem. Default browser on the Samsung S3 also exhibits this issue. – FloatingRock Sep 24 '13 at 11:42
  • Just as an test, what if you dont display the underlaying body at all while viewing the modal? (instead view a image as reference) – DannyThunder Sep 24 '13 at 12:51
  • @DannyThunder doable, but that sounds hacky. The underlying content is dynamic I'd need to figure out a way to get it to take a snapshot before hand. – FloatingRock Sep 26 '13 at 05:25
  • Why does the modal.on shown not fired in jsBin ? Do you have any specific reaso for that – Anobik Sep 28 '13 at 19:41
  • @Anobik it is fired. It just doesn't have an effect on the body for some reason - and it still scrolls regardless (hence, the question) – FloatingRock Sep 28 '13 at 20:50
  • I do have a work around but don't know You will accept or not. Will have to add some code snippet. A bit more coding. :) – Anobik Sep 29 '13 at 13:13
  • @Anobik: try me .. i'm getting desperate, in case you can't tell ;) – FloatingRock Sep 29 '13 at 18:56
  • :) to the rescue dude . Might have some minor side effect . Can be fixed though :) but major problem gets solved. :) – Anobik Sep 29 '13 at 18:58
  • try this . :) let me know if it solves the issue. I still have bugs . But not related to the question :) http://fiddle.jshell.net/aRUbZ/42/show/ – Anobik Sep 29 '13 at 19:00
  • Still scrolls the body on my iPhone 4S / iOS7 Safari browser :( – FloatingRock Sep 29 '13 at 19:07
  • Not happening in my note 8 :( dont have iphone or ipad :( – Anobik Sep 29 '13 at 19:08
  • ill check from ipad and let you know . I guess some event missing . :) – Anobik Sep 29 '13 at 19:10
  • try closing the popup if it loads as soon as page comes up and then opening again – Anobik Sep 29 '13 at 19:28
  • @Anobik: Looks like you haven't set the `viewport` `` tag. That might be causing this issue. It's also why I prefer using JSBin (because you can set the `meta` tags directly) – FloatingRock Sep 30 '13 at 04:31
  • ok then ill give a js bi try :) – Anobik Sep 30 '13 at 04:33
  • http://jsbin.com/IqUrov/1 check this and let me now if working in iphone or any ios device of yours . Incorporated all the viewport and meta tags from ur code only :) – Anobik Sep 30 '13 at 04:38
  • @Anobik: Works! Looks crazy hacky though - nloko's answer below nips the problem at the bud. Thanks – FloatingRock Sep 30 '13 at 04:46
  • position : fixed although makes screen fliker in my tab :) when try to scroll . – Anobik Sep 30 '13 at 04:47
  • Dude you accepted and even awarded the bounty to a wrongs answer. That 50,000 user's statement you made gonna go to 25000 only :P try in android the same crack which you accepted. – Anobik Sep 30 '13 at 04:56

8 Answers8

12

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.

FloatingRock
  • 6,741
  • 6
  • 42
  • 75
Sven Finger
  • 543
  • 3
  • 11
  • Works great - except now the body won't scroll, even after the modal has closed. – FloatingRock Sep 27 '13 at 18:53
  • 1
    Applying the CSS via the shown.bs.modal Event and removing it again on the hidden.bs.modal Event should do the Trick. – Sven Finger Sep 29 '13 at 02:39
  • 1
    I reviewed my code. You can use the .modal-open Class like this: http://jsbin.com/aXoMaGo/6 I tested it on Safari/Chrome on iOS 7 again and it's working. – Sven Finger Sep 30 '13 at 07:34
  • I picked this as the correct answer, because it doesn't even require any javascript. Works on my iPhone w/iOS7 and Samsung S3 - the only devices I have lying around. (Final Solution w/just CSS: http://jsbin.com/aXoMaGo/10/edit) – FloatingRock Sep 30 '13 at 12:15
  • @FloatingRock your solution works, but the scrolling is broken. It is no longer smooth. And the page scrolls to top. The solution offered by Sven has a nice smooth scroll, but also scrolls to top every time. – Kristjan Liiva Dec 15 '15 at 15:58
  • Hello, Can you please update your answer to remove the links to the jsbin's that don't work and put in the link to jsbin.com/aXoMaGo/6 . That jsbin works perfectly on both desktop (Windows 10, Firefox 49) and Android 5.0 (Moto G 2nd Gen), i.e. scroll work properly once the modal is closed. – carbontracking Nov 22 '16 at 15:06
  • It scrolls to the top if the button is placed say after the first fold. Since the button is placed at the top in the jsbin link it's looking fine which it is not. – kkdeep Nov 28 '20 at 08:38
3

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.

Ollie Williams
  • 1,996
  • 3
  • 25
  • 41
2

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;
}
am80l
  • 1,511
  • 12
  • 11
2

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: ''
    });
  });
});
nloko
  • 696
  • 4
  • 11
  • Dude this is not a solution for Android . My note 8 doesnot even respond to touch gesture as it is fixed. no scroll even. – Anobik Sep 30 '13 at 04:52
1

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 :)

Anobik
  • 4,841
  • 2
  • 17
  • 32
  • The accepted answer works on my friends Samsung Galaxy S3's native and Chrome browsers. Your solution works as well, and I appreciate the effort you've put in finding a solution that works. Thanks Anobik! – FloatingRock Sep 30 '13 at 12:03
  • Ok thanks :) but please test on different devices. My tab it does not work unfortunately :( – Anobik Sep 30 '13 at 12:04
  • One problem with the "position:fixed" solution is that the page jumps to the top. It does jump back to where you were, but its not a 100% solution – Camathon Dec 01 '14 at 15:09
1

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);  
                  });
    }
AliShafiee
  • 11
  • 1
0

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>
AliShafiee
  • 11
  • 1
0

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);

}
Judson Terrell
  • 4,204
  • 2
  • 29
  • 45
  • My solution works on both mobile and desktop without shifting the body left or up. – Judson Terrell Feb 05 '15 at 16:47
  • Did you face any issues with the accepted answer? http://jsbin.com/aXoMaGo/10/edit – FloatingRock Feb 06 '15 at 05:30
  • Yes. If you have a layout that is centered, it forces the layout to the left position when you apply fixed positioning which looks bad. You essentially lose your initial scroll position on the page. Basically when the dialog opens, everything shifts to the left and scrolls to the top. I have a site www.meyearly.com login and add some photos to the album, click on one. You will see mine in action. – Judson Terrell Feb 06 '15 at 11:42
  • I want to add that your solution may work strictly for mobile, but I always like to cover all scenarios. – Judson Terrell Feb 06 '15 at 11:43
  • You can use google chrome mobile emulator. Btw. Also if you want I can apply my code to your js bin to be more specific to your need. – Judson Terrell Feb 06 '15 at 11:47
  • Well, the issue only manifests on mobile devices. It works fine on other devices AFAIK. Still, if your solution works too then great. I did not notice the shifting issue you raised on my iPhone 4S, but I haven't tried a bunch of devices so that may be it. – FloatingRock Feb 06 '15 at 16:30