Disable double-tap "zoom" option in browser on touch devices

HtmlBrowserTouchZooming

Html 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

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
QuestionWouter KonecnyView Question on Stackoverflow
Solution 1 - HtmlRoss AllenView Answer on Stackoverflow
Solution 2 - HtmlKablamView Answer on Stackoverflow
Solution 3 - HtmlRockster160View Answer on Stackoverflow
Solution 4 - HtmlJayView Answer on Stackoverflow
Solution 5 - HtmlWouter KonecnyView Answer on Stackoverflow
Solution 6 - HtmlEvrim PersembeView Answer on Stackoverflow
Solution 7 - HtmlJonathan Morales VélezView Answer on Stackoverflow
Solution 8 - HtmlErçin DedeoğluView Answer on Stackoverflow
Solution 9 - HtmlWilliam GraselView Answer on Stackoverflow
Solution 10 - HtmlSølve TornøeView Answer on Stackoverflow
Solution 11 - Htmlprohibited509View Answer on Stackoverflow
Solution 12 - HtmlDally SView Answer on Stackoverflow
Solution 13 - HtmlK. Kilian LindbergView Answer on Stackoverflow
Solution 14 - HtmlEvelina MichailovaView Answer on Stackoverflow
Solution 15 - HtmlPeterView Answer on Stackoverflow
Solution 16 - HtmlÁsgeir FrímannssonView Answer on Stackoverflow
Solution 17 - HtmlnotsureView Answer on Stackoverflow