3
votes

I need my web application to behave as a native mobile app. For this I needed to prevent pinch-to-zoom and double tap zooming on all browsers. In Chrome and Firefox it was easy:

<meta name="viewport" content="width=device-width, user-scalable=no" />

On Safari its a challenge. Here I found how to prevent pinch-to-zoom and to disable double-tap-zoom. But when you are scrolling and pinching to zoom, its zooming. My question is if there is way to block it also on scrolling?

2
Please don't do that, that breaks the expected behaviour, that is bad UX - if something is too small I want to zoom in on it. - luk2302
I know this is bad practice. But boss want this behavior. - Ivan Cherevko
This isn't a bad practice at all. That's just kool-aid from Apple masquerading as an accessibilty feature. The decision to enable or disable behavior of a web page must be left with web developers. - Marvin Danig

2 Answers

-1
votes

Combined with the javascript preventDefault solution in your link; you can use the following to disable pinch in and out page-wide.

<style>
html,
body {
  position: fixed;
  overflow: hidden;
}
</style>

And wrap everything inside <body> in a master wrapper with the following CSS

<style>
.mainwrapper {
  width: 100vw;
  height: 100vh;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
}
</style>

<body>
    <div id="master_wrap">
        ...content...
    </div> <!-- /master wrapper -->
</body>

You in effect disable all body/html level scrolling, and then re-enable scrolling a level below inside the master wrapper, which includes elastic and momentum scrolling. When these elements scroll, the pinching is already ignored.

Drawbacks

1 - If you have fixed or absolute elements, then the scrolling becomes very janky.

2 - There also seems to be a strange bug where-by part of the page will be modified, and pinch becomes available again, if you scroll down from high on the page. I think it might be related to the vh property and there's probably a JS solution to set the element height/width better.

-1
votes

If you want to ignore all events that can scroll the body content, you can bind a function to the touchmove event that prevents default behavior and stop propagation of the event:

document.body.addEventListener("touchmove", function(event) {
    event.preventDefault();
    event.stopPropagation();
}, false);

In jQuery or similar libraries:

$(document.body).on("touchmove", function(event) {
    event.preventDefault();
    event.stopPropagation();
});

Link