Disable double-tap "zoom" option in browser on touch devices
HtmlBrowserTouchZoomingHtml Problem Overview
I want to disable the double-tap zoom functionality on specified elements in the browser (on touch devices), without disabling all the zoom functionality.
For example: One element can be tapped multiple times for something to happen. This works fine on desktop browsers (as expected), but on touch device browsers, it will zoom in.
Html Solutions
Solution 1 - Html
Note (as of 2020-08-04): this solution does not appear to work in iOS Safari v12+. I will update this answer and delete this note once I find a clear solution that covers iOS Safari.
CSS-only solution
Add touch-action: manipulation
to any element on which you want to disable double tap zoom, like with the following disable-dbl-tap-zoom
class:
.disable-dbl-tap-zoom {
touch-action: manipulation;
}
<button>plain button</button>
<button class="disable-dbl-tap-zoom">button with disabled double-tap zoom</button>
<p>A <b>plain</b> paragraph. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>
<p class="disable-dbl-tap-zoom">A paragraph <b>with disabled double-tap zoom</b>. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>
From the touch-action
docs (emphasis mine):
> manipulation > > Enable panning and pinch zoom gestures, but disable additional non-standard gestures such as double-tap to zoom.
This value works on Android and on iOS.
Solution 2 - Html
<head>
<title>Site</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
etc...
</head>
I've used that very recently and it works fine on iPad. Haven't tested on Android or other devices (because the website will be displayed on iPad only).
Solution 3 - Html
I know this may be old, but I found a solution that worked perfectly for me. No need for crazy meta tags and stopping content zooming.
I'm not 100% sure how cross-device it is, but it worked exactly how I wanted to.
$('.no-zoom').bind('touchend', function(e) {
e.preventDefault();
// Add your code here.
$(this).click();
// This line still calls the standard click event, in case the user needs to interact with the element that is being clicked on, but still avoids zooming in cases of double clicking.
})
This will simply disable the normal tapping function, and then call a standard click event again. This prevents the mobile device from zooming, but otherwise functions as normal.
EDIT: This has now been time-tested and running in a couple live apps. Seems to be 100% cross-browser and platform. The above code should work as a copy-paste solution for most cases, unless you want custom behavior before the click event.
Solution 4 - Html
CSS to disable double-tap zoom globally (on any element):
* {
touch-action: manipulation;
}
> manipulation > > Enable panning and pinch zoom gestures, but disable additional non-standard gestures such as double-tap to zoom.
Thanks Ross, my answer extends his: https://stackoverflow.com/a/53236027/9986657
Solution 5 - Html
I just wanted to answer my question properly as some people do not read the comments below an answer. So here it is:
(function($) {
$.fn.nodoubletapzoom = function() {
$(this).bind('touchstart', function preventZoom(e) {
var t2 = e.timeStamp
, t1 = $(this).data('lastTouch') || t2
, dt = t2 - t1
, fingers = e.originalEvent.touches.length;
$(this).data('lastTouch', t2);
if (!dt || dt > 500 || fingers > 1) return; // not double-tap
e.preventDefault(); // double tap - prevent the zoom
// also synthesize click events we just swallowed up
$(this).trigger('click').trigger('click');
});
};
})(jQuery);
I did not write this, i just modified it. I found the iOS-only version here: https://gist.github.com/2047491 (thanks Kablam)
Solution 6 - Html
If you need a version that works without jQuery, I modified Wouter Konecny's answer (which was also created by modifying this gist by Johan Sundström) to use vanilla JavaScript.
function preventZoom(e) {
var t2 = e.timeStamp;
var t1 = e.currentTarget.dataset.lastTouch || t2;
var dt = t2 - t1;
var fingers = e.touches.length;
e.currentTarget.dataset.lastTouch = t2;
if (!dt || dt > 500 || fingers > 1) return; // not double-tap
e.preventDefault();
e.target.click();
}
Then add an event handler on touchstart
that calls this function:
myButton.addEventListener('touchstart', preventZoom);
Solution 7 - Html
You should set the css property touch-action
to none
as described in this other answer https://stackoverflow.com/a/42288386/1128216
.disable-doubletap-to-zoom {
touch-action: none;
}
Solution 8 - Html
* {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
Disable double tap to zoom on touch screens. Internet explorer included.
Solution 9 - Html
Simple prevent the default behavior of click
, dblclick
or touchend
events will disable the zoom functionality.
If you have already a callback on one of this events just call a event.preventDefault()
.
Solution 10 - Html
If there is anyone like me who is experiencing this issue using Vue.js,
simply adding .prevent will do the trick: @click.prevent="someAction"
Solution 11 - Html
If you only want to prevent double click zoom across all devices, try setting the dblclick
event listener of the button to preventDefault()
. This worked for me!
edit: typo in 'dblclick'
const button = document.querySelector('#button');
button.addEventListener('dblclick', function(el) {
el.preventDefault();
});
<button id="button"> No double click zoom here</button>
Solution 12 - Html
This will prevent double tap zoom on elements in 'body' this can be changed to any other selector
$('body').bind('touchstart', function preventZoom(e){
var t2 = e.timeStamp;
var t1 = $(this).data('lastTouch') || t2;
var dt = t2 - t1;
var fingers = e.originalEvent.touches.length;
$(this).data('lastTouch', t2);
if (!dt || dt > 500 || fingers > 1){
return; // not double-tap
}
e.preventDefault(); // double tap - prevent the zoom
// also synthesize click events we just swallowed up
$(e.target).trigger('click');
});
But this also prevented my click event from triggering when clicked multiple times so i had to bind a another event to trigger the events on multiple clicks
$('.selector').bind('touchstart click', preventZoom(e) {
e.stopPropagation(); //stops propagation
if(e.type == "touchstart") {
// Handle touchstart event.
} else if(e.type == "click") {
// Handle click event.
}
});
On touchstart i added the code to prevent the zoom and trigger a click.
$('.selector').bind('touchstart, click', function preventZoom(e){
e.stopPropagation(); //stops propagation
if(e.type == "touchstart") {
// Handle touchstart event.
var t2 = e.timeStamp;
var t1 = $(this).data('lastTouch') || t2;
var dt = t2 - t1;
var fingers = e.originalEvent.touches.length;
$(this).data('lastTouch', t2);
if (!dt || dt > 500 || fingers > 1){
return; // not double-tap
}
e.preventDefault(); // double tap - prevent the zoom
// also synthesize click events we just swallowed up
$(e.target).trigger('click');
} else if(e.type == "click") {
// Handle click event.
"Put your events for click and touchstart here"
}
});
Solution 13 - Html
Here's a variation that currently, as of 2022, does the trick on most device versions; Android / iOS. Note that for example iOS 14+ zooms in on any text input fields that has a font-size of less than 1rem 16px, which also quite senior pros seem to have missed.
A vanilla javascript example - that can be improved further - for example with logic to allow normal behavior scenarios too - so for your experimentation.
document.getElementById('selectorid').addEventListener('touchend' || 'dblclick', event => {
event.preventDefault();
event.stopImmediatePropagation();
}, {
passive: false
});
Here's a more covering example for testing purposes to see if it achieves wished results. This one affects all the elements on the page inherited in the DOM.
/* For testing purposes, overrides events that may trigger a "zoom"; note that this may cause other unexpected behavior */
window.addEventListener('touchmove' || 'touchdowm' || 'touchend' || 'mousedown' || 'dblclick', event => {
event.preventDefault();
event.stopImmediatePropagation();
}, {
passive: false
});
Here's some simple CSS, for overriding test purposes - try it out on the page and you may expect a remedy clue if form fields are what's bugging. Although the minimum size of 16px is actually quite wishfully intentional for accesibillity concerns. Note that the "!important" flag isn't considered good practice to manifest in a production deploy.
/* CSS to test prevention of zoom when interacting with input fields */
input[type=text] {
font-size: 1rem !important;
}
Solution 14 - Html
most of the coding above doesn't work unfortunately these simple lines will do it
document.addEventListener('dblclick', function(event) {
event.preventDefault();
}, { passive: false });
Solution 15 - Html
I assume that I do have a <div>
input container area with text, sliders and buttons in it, and want to inhibit accidental double-taps in that <div>
.
The following does not inhibit zooming on the input area, and it does not relate to double-tap and zooming outside my <div>
area. There are variations depending on the browser app.
I just tried it.
(1) For Safari on iOS, and Chrome on Android, and is the preferred method. Works except for Internet app on Samsung, where it disables double-taps not on the full <div>
, but at least on elements that handle taps. It returns return false
, with exception on text
and range
inputs.
$('selector of <div> input area').on('touchend',disabledoubletap);
function disabledoubletap(ev) {
var preventok=$(ev.target).is('input[type=text],input[type=range]');
if(preventok==false) return false;
}
(2) Optionally for built-in Internet app on Android (5.1, Samsung), inhibits double-taps on the <div>
, but inhibits zooming on the <div>
:
$('selector of <div> input area').on('touchstart touchend',disabledoubletap);
(3) For Chrome on Android 5.1, disables double-tap at all, does not inhibit zooming, and does nothing about double-tap in the other browsers.
The double-tap-inhibiting of the <meta name="viewport" ...>
is irritating, because <meta name="viewport" ...>
seems good practice.
<meta name="viewport" content="width=device-width, initial-scale=1,
maximum-scale=5, user-scalable=yes">
Solution 16 - Html
Using CSS touch-events: none Completly takes out all the touch events. Just leaving this here in case someone also has this problems, took me 2 hours to find this solution and it's only one line of css. https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
Solution 17 - Html
Here we go