Bootstrap modal iOS momentum issue
Recently on one of the projects using Bootstrap 3 I encountered really weird bug – when the modal is opened, you can scroll the underlay.
In theory you have a backdrop over main body content, and only modal should be scrolled. No actions on page content itself.
In some cases it was not only aesthetic problem. My modal even stopped reacting on touch actions. The body was scrolled instead.
I have read tons of articles, and issue was using css property -webkit-overflow-scrolling: touch; on my Bootstrap modal.
If you don’t use this, you have really poor scrolling experience. The css rule applies so called infinite (or momentum) scrolling.
So, imagine you have this HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <body> <!-- main page wrapper div is going here --> <div class="page-wrapper"> <!-- your page header... --> <header>...</header> <!-- ...content... --> <div class="main-content">...</div> <!-- ...and footer --> </footer> </div> <!-- standard Bootstrap 3 modal code here --> <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">...</div> </body> |
Then, in your custom modal .less file add following lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | .modal-open { @media only screen and (min-resolution:150dpi) and (max-width: @screen-sm), only screen and (-webkit-min-device-pixel-ratio:1.5) { height: 100%; position:absolute; overflow:hidden; -webkit-overflow-scrolling: auto; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-transform: translateZ(0); >.page, >.footer, >.header{ display: none; } .modal { position: relative; overflow-y: scroll !important; -webkit-overflow-scrolling: touch; -webkit-backface-visibility: hidden; -webkit-transform: translateZ(0px); -webkit-transform: translate3d(0,0,0); -webkit-perspective: 1000; transform: none; } } } |
Please, make sure that your modal has class .modal-open when it’s opened.
In my case, I had a modal with the height larger than mobile screen.
So, a pretty nice solution was to make modal full screen.
So that I have no scroll issues when I open modal – it should be always scrolled to top, and the page saved its scroll position when the modal is closed, I added few jQuery lines (as you are using Bootstrap jQuery is OK here):
1 2 3 4 5 6 7 8 9 10 11 12 13 | if($(window).width()<768){ var st; $('.modal').on('show.bs.modal', function () { st = $(window).scrollTop(); }); $('.modal').on('shown.bs.modal', function () { $('.page-wrapper').hide(); }); $('.modal').on('hide.bs.modal', function () { $('.page-wrapper').show(); $('body,html').scrollTop(st); }); } |
Hope this will work for you!