ipad safari: disable scrolling, and bounce effect?

IpadScrollMobile SafariBounce

Ipad Problem Overview


I'm working on a browser based app, currently I'm developing and styling for the ipad safari browser.

I'm looking for two things on the ipad: How can I disable vertical scrolling for pages that don't require it? & how can I disable the elastic bounce effect?

Ipad Solutions


Solution 1 - Ipad

This answer is no longer applicable, unless you are developing for a very old iOS device... Please see other solutions


2011 answer: For a web/html app running inside iOS Safari you want something like

document.ontouchmove = function(event){
    event.preventDefault();
}

For iOS 5 you may want to take the following into account: https://stackoverflow.com/questions/7798201/document-ontouchmove-and-scrolling-on-ios-5

Update September 2014: A more thorough approach can be found here: https://github.com/luster-io/prevent-overscroll. For that and a whole lot of useful webapp advice, see http://www.luster.io/blog/9-29-14-mobile-web-checklist.html</s>

Update March 2016: That last link is no longer active - see https://web.archive.org/web/20151103001838/http://www.luster.io/blog/9-29-14-mobile-web-checklist.html for the archived version instead. Thanks @falsarella for pointing that out.

Solution 2 - Ipad

You can also change the position of the body/html to fixed:

body,
html {
  position: fixed;
}

Solution 3 - Ipad

To prevent scrolling on modern mobile browsers you need to add the passive: false. I had been pulling my hair out getting this to work until I found this solution. I have only found this mentioned in one other place on the internet.

function preventDefault(e){
    e.preventDefault();
}

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault);
}

Solution 4 - Ipad

You can use this jQuery code snippet to do this:

$(document).bind(
	  'touchmove',
		  function(e) {
		    e.preventDefault();
		  }
);

This will block the vertical scrolling and also any bounce back effect occurring on your pages.

Solution 5 - Ipad

overflow: scroll;
-webkit-overflow-scrolling: touch;

On container you can set bounce effect inside element

Source: http://www.kylejlarson.com/blog/2011/fixed-elements-and-scrolling-divs-in-ios-5/

Solution 6 - Ipad

I know this is slightly off-piste but I've been using Swiffy to convert Flash into an interactive HTML5 game and came across the same scrolling issue but found no solutions that worked.

The problem I had was that the Swiffy stage was taking up the whole screen, so as soon as it had loaded, the document touchmove event was never triggered.

If I tried to add the same event to the Swiffy container, it was replaced as soon as the stage had loaded.

In the end I solved it (rather messily) by applying the touchmove event to every DIV within the stage. As these divs were also ever-changing, I needed to keep checking them.

This was my solution, which seems to work well. I hope it's helpful for anyone else trying to find the same solution as me.

var divInterval = setInterval(updateDivs,50);
function updateDivs(){
$("#swiffycontainer > div").bind(
	'touchmove',
	 function(e) {
		e.preventDefault();
	}
);}

Solution 7 - Ipad

Code to To remove ipad safari: disable scrolling, and bounce effect

   document.addEventListener("touchmove", function (e) {
		e.preventDefault();
	}, { passive: false });

If you have canvas tag inside document, sometime it will affect the usability of object inside Canvas(example: movement of object); so add below code to fix it.

	document.getElementById("canvasId").addEventListener("touchmove", function (e) {
		e.stopPropagation();
	}, { passive: false });

Solution 8 - Ipad

none of the solutions works for me. This is how I do it.

  html,body {
      position: fixed;
      overflow: hidden;
    }
  .the_element_that_you_want_to_have_scrolling{
      -webkit-overflow-scrolling: touch;
  }

Solution 9 - Ipad

Try this JS sollutuion:

var xStart, yStart = 0; 

document.addEventListener('touchstart', function(e) {
    xStart = e.touches[0].screenX;
    yStart = e.touches[0].screenY;
}); 

document.addEventListener('touchmove', function(e) {
    var xMovement = Math.abs(e.touches[0].screenX - xStart);
    var yMovement = Math.abs(e.touches[0].screenY - yStart);
    if((yMovement * 3) > xMovement) {
        e.preventDefault();
    }
});

Prevents default Safari scrolling and bounce gestures without detaching your touch event listeners.

Solution 10 - Ipad

Tested in iphone. Just use this css on target element container and it will change the scrolling behaviour, which stops when finger leaves the screen.

-webkit-overflow-scrolling: auto

https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling

Solution 11 - Ipad

For those who are using MyScript the Web App and are struggling with the body scrolling/dragging (on iPad and Tablets) instead of actually writing:

<body touch-action="none" unresolved>

That fixed it for me.

Solution 12 - Ipad

You can use js for prevent scroll:

let body = document.body;

let hideScroll = function(e) {
  e.preventDefault();
};

function toggleScroll (bool) {

  if (bool === true) {
    body.addEventListener("touchmove", hideScroll);
  } else {
    body.removeEventListener("touchmove", hideScroll);
  }
}

And than just run/stop toggleScroll func when you opnen/close modal.

Like this toggleScroll(true) / toggleScroll(false)

(This is only for iOS, on Android not working)

Solution 13 - Ipad

Try this JS solution that toggles webkitOverflowScrolling style. The trick here is that this style is off, mobile Safari goes to ordinary scrolling and prevents over-bounce — alas, it is not able to cancel ongoing drag. This complex solution also tracks onscroll as bounce over the top makes scrollTop negative that may be tracked. This solution was tested on iOS 12.1.1 and has single drawback: while accelerating the scroll single over-bounce still happens as resetting the style may not cancel it immediately.

function preventScrollVerticalBounceEffect(container) {
  setTouchScroll(true) //!: enable before the first scroll attempt

  container.addEventListener("touchstart", onTouchStart)
  container.addEventListener("touchmove", onTouch, { passive: false })
  container.addEventListener("touchend", onTouchEnd)
  container.addEventListener("scroll", onScroll)

  function isTouchScroll() {
    return !!container.style.webkitOverflowScrolling
  }

  let prevScrollTop = 0, prevTouchY, opid = 0

  function setTouchScroll(on) {
    container.style.webkitOverflowScrolling = on ? "touch" : null

    //Hint: auto-enabling after a small pause makes the start
    // smoothly accelerated as required. After the pause the
    // scroll position is settled, and there is no delta to
    // make over-bounce by dragging the finger. But still,
    // accelerated content makes short single over-bounce
    // as acceleration may not be off instantly.

    const xopid = ++opid
    !on && setTimeout(() => (xopid === opid) && setTouchScroll(true), 250)

    if(!on && container.scrollTop < 16)
      container.scrollTop = 0
    prevScrollTop = container.scrollTop
  }

  function isBounceOverTop() {
    const dY = container.scrollTop - prevScrollTop
    return dY < 0 && container.scrollTop < 16
  }

  function isBounceOverBottom(touchY) {
    const dY = touchY - prevTouchY

    //Hint: trying to bounce over the bottom, the finger moves
    // up the screen, thus Y becomes smaller. We prevent this.

    return dY < 0 && container.scrollHeight - 16 <=
      container.scrollTop + container.offsetHeight
  }

  function onTouchStart(e) {
    prevTouchY = e.touches[0].pageY
  }

  function onTouch(e) {
    const touchY = e.touches[0].pageY

    if(isBounceOverBottom(touchY)) {
      if(isTouchScroll())
        setTouchScroll(false)
      e.preventDefault()
    }

    prevTouchY = touchY
  }

  function onTouchEnd() {
    prevTouchY = undefined
  }

  function onScroll() {
    if(isTouchScroll() && isBounceOverTop()) {
      setTouchScroll(false)
    }
  }
}

Solution 14 - Ipad

improved answer @Ben Bos and commented by @Tim

This css will help prevent scrolling and performance issue with css re-render because position changed / little lagging without width and height

html,
body {
  position: fixed;
  width: 100%; 
  height: 100%
}

Solution 15 - Ipad

Consider the following architecture:

<body> <div id="root"></div> </body>

this css will work:

#root { position: fixed; height: 100%; overflow: auto; }

Solution 16 - Ipad

For those of you who don't want to get rid of the bouncing but just to know when it stops (for example to start some calculation of screen distances), you can do the following (container is the overflowing container element):

    const isBouncing = this.container.scrollTop < 0 ||
    this.container.scrollTop + this.container.offsetHeight >
        this.container.scrollHeight

Solution 17 - Ipad

Disable safari bounce scrolling effect:

html,
body {
  height: 100%;
  width: 100%;
  overflow: auto;
  position: fixed;
}  

Solution 18 - Ipad

I had an issue with grabbing the html element in the background, when a menu with scroll was open and either at the top or at the bottom at the scroll height. I tried lots of things. Setting html position to fixed was the closest I got to lock the screen, but in the PWA it resulted in a white area at the bottom, that I couldn't fix. Finally I've found a solution, that worked for me :

html {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

body {
    margin: 0;
    height: calc(100vh - 1px)
    overflow: hidden;
    background-color: 'Whatever color you need to hide the 1px at the bottom'
}

Because it only seems to be an issue on iOS, I have targeted the devices from iPhone X to 12 Pro Max:

body {
    margin: 0;
    overflow: hidden;
    background-color: '#TIP: You can use the color picker from the inspector';

    @media only screen and (min-width: 375px) and (max-height: 926px) and (-webkit-device-pixel-ratio: 3) {
        height: calc(100vh - 1px);
    }
}

This is preventing any kind of scroll, touch or grab in the html or body elements, and scroll is still working in the menu or where else specified. Cheers.

Solution 19 - Ipad

body {
   touch-action:none;
}

Using JQuery

// Disable
$("body").css({ "touch-action": "none" })

// Enable
$("body").css({ "touch-action": "auto" })

Solution 20 - Ipad

Similar to angry kiwi I got it to work using height rather than position:

html,body {
  height: 100%;
  overflow: hidden;
}

.the_element_that_you_want_to_have_scrolling{
  -webkit-overflow-scrolling: touch;
}

Solution 21 - Ipad

Solution tested, works on iOS 12.x

This is problem I was encountering :

<body> <!-- the whole body can be scroll vertically -->
  <article>

    <my_gallery> <!-- some picture gallery, can be scroll horizontally -->
    </my_gallery>

  </article>
</body>

While I scrolling my gallery, the body always scrolling itself (human swipe aren't really horizontal), that makes my gallery useless.

Here's what I did while my gallery start scrolling

var html=jQuery('html');
html.css('overflow-y', 'hidden');
//above code works on mobile Chrome/Edge/Firefox
document.ontouchmove=function(e){e.preventDefault();} //Add this only for mobile Safari

And when my gallery end its scrolling...

var html=jQuery('html');
html.css('overflow-y', 'scroll');
document.ontouchmove=function(e){return true;}

Hope this helps~

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdamView Question on Stackoverflow
Solution 1 - IpadOskar AustegardView Answer on Stackoverflow
Solution 2 - IpadBen BosView Answer on Stackoverflow
Solution 3 - IpadChristopher VickersView Answer on Stackoverflow
Solution 4 - IpadAlessandro IncarnatiView Answer on Stackoverflow
Solution 5 - Ipaduser956584View Answer on Stackoverflow
Solution 6 - IpadTomView Answer on Stackoverflow
Solution 7 - IpadTejashwini V BView Answer on Stackoverflow
Solution 8 - Ipadangry kiwiView Answer on Stackoverflow
Solution 9 - IpadAndrii VerbytskyiView Answer on Stackoverflow
Solution 10 - Ipaduser1021364View Answer on Stackoverflow
Solution 11 - IpadMiroView Answer on Stackoverflow
Solution 12 - IpadVlad NovikovView Answer on Stackoverflow
Solution 13 - IpadAnton BaukinView Answer on Stackoverflow
Solution 14 - Ipadauronsan zenxView Answer on Stackoverflow
Solution 15 - IpadShahriarView Answer on Stackoverflow
Solution 16 - IpadPhilView Answer on Stackoverflow
Solution 17 - IpadAbolfazl BaghshahiView Answer on Stackoverflow
Solution 18 - IpadMajeView Answer on Stackoverflow
Solution 19 - IpadSynchroView Answer on Stackoverflow
Solution 20 - Ipadaustinh7View Answer on Stackoverflow
Solution 21 - IpadRRTWView Answer on Stackoverflow