Skip to content

Instantly share code, notes, and snippets.

@gajus
Last active July 29, 2024 14:16
Show Gist options
  • Save gajus/bbf06ea2e37047b01e70 to your computer and use it in GitHub Desktop.
Save gajus/bbf06ea2e37047b01e70 to your computer and use it in GitHub Desktop.

The issue:

..mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap.

(from a new defunct https://developers.google.com/mobile/articles/fast_buttons article)

touch-action CSS property can be used to disable this behaviour.

touch-action: manipulation The user agent may consider touches that begin on the element only for the purposes of scrolling and continuous zooming. Any additional behaviors supported by auto are out of scope for this specification.

https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action#Values

touch-action is now supported by all major mobile browsers.

Note that iOS 9.3 has not been released yet. (2016 02 13)

In ./webpack.js I am first detecting if the touch-action property is supported. If it is, I am using it to set the style of document.body. If it is not, then I am using webpack require.ensure to download FastClick polyfill to fix the issue.

if ('touchAction' in document.body.style) {
document.body.style.touchAction = 'manipulation';
} else {
require.ensure(['fastclick'], (require) => {
const FastClick = require('fastclick');
window.addEventListener('load', () => {
FastClick.attach(document.body);
});
}, 'fastclick');
}
@simevidas
Copy link

Correct me if I'm wrong, but just having the viewport meta tag should be enough to disable the tap delay in all browsers (incl. upcoming Safari 9.1), so setting touch-action on body should not be needed for responsive (i.e. mobile-optimized) pages.

@dylanb
Copy link

dylanb commented Feb 13, 2016

@simevedas if you disable zooming, you introduce a problem for people with low vision and also violate a WCAG guideline.https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-scale.html

@ablank
Copy link

ablank commented Feb 13, 2016

@simevidas
Copy link

@dylanb The standard viewport meta tag does not disable zooming. For instance, I use this one:

<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">

The above code should ensure that there is no tap delay in all mobile browsers, incl. Safari. Again, correct me if I'm wrong.

@marvindanig
Copy link

@dylanb I'd take the WCAG guidelines with a pinch of salt.

For example, the guidelines haven't considered a web outside of the scroll container. You see scrolling is no longer the only way to consume media on touch capable devices. You can also flip pages like a book. This is relevant because it usually gets hard to scroll down a 5000 words essay on a mobile. The post thins down into a thick never-ending scroll, almost like billing paper, and people then struggle between scrolling-down carefully and zooming-in until they give up halfway. The same post is usually a short/flat scroll that is just 3 pages long on the desktop.

I think WCAG should reconsider these ideas ground up for they are only porting old ideas from the old web at the moment. We have a web that doesn't rely on pointing devices!

Another case for the point: WG hasn't considered the idea that typography could be scaled responsively and exactly with viewport units. Without developers needing to maintain and construct layouts with complicated break-points using @media-queries. How many break-points will make it good to suit all the screens out there? Handling it with unscalable typography (em/pt/px/% whatever) with 3/4 break-points itself is expensive, unmaintainable and messy. It is in this context allowing zoom to scale is also a totally useless idea. Because the text can be scaled legibly with vw units alone; and far better than it has been agreed upon by the WCAG (range 0<zoom<200%). And have the page-scroll remaining "taut" on the mobile screen (which is why people disable zoom in the first place).

In my opinion accessibility/standards need to revisit these ideas keeping distance from the desktop-only web of the 90s. Avoid pushing that monoculture and messy unmaintainable definitions that no longer hold good. Just a thought.

@neilbaylor
Copy link

@simevidas that will disable the 300ms in Chrome 32+ on Android

For other browsers, you'll also need user-scalable=no to disable the delay

IMO, the new holy grail will be
<meta name="viewport" content="width=device-width,initial-scale=1"> with touch-action applied to all clickable elements

@corporatepiyush
Copy link

Awesome. Thanks a lot for sharing this GIST.

@simevidas
Copy link

@neilbayor Not just Chrome. It disables the delay in a range of browsers http://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay. If the page is responsive (mobile-friendly), the viewport meta tag is enough, according to that table. Not sure what the fascination with touch-action is, but the table shows that it’s not needed. (Please don’t cargo cult.)

@alekseykulikov
Copy link

Hey @gajus. Thank you for sharing!
I've just published a module that does the same as your gist, but loads FastClick from CDN when needed https://github.com/alekseykulikov/touch-action

@Eccenux
Copy link

Eccenux commented Feb 22, 2016

Double tap was removed from major browsers for sties using width=device-width.

So touch-action is probably only important for Windows Phone (if you care for a dying platform). As seems touch-action support is actually worse in terms of mobile share.

@Itrulia
Copy link

Itrulia commented Feb 24, 2016

@simevidas not entirely, ng-click still has the delay for me even with the viewport tag

@simevidas
Copy link

@Itrulia Sounds like an issue with Angular. I can debug if you make a demo.

@Itrulia
Copy link

Itrulia commented Feb 24, 2016

@simevidas Yeah just found why it happened on that one site (I asked myself too why it happened), because it had 1-2px of horizontal scrolling :/

@gregblass
Copy link

Awesome, thanks for this! BTW you got mentioned in a smashing magazine post.

@patrickhlauke
Copy link

@simevidas

If the page is responsive (mobile-friendly), the viewport meta tag is enough, according to that table. Not sure what the fascination with touch-action is, but the table shows that it’s not needed.

Personally, I like the explicit, declarative nature of having a rule in my styles that clearly states the browser's intended behavior, rather than relying on magical heuristics (even if they're becoming universal) like width=device-width. But you're correct that pragmatically, all main browsers are (finally, once iOS 9.3 is out) adopting this optimisation. Still, I'm hoping Firefox/Android (the last major player to drag its heels) will implement this soon.

As a side note, on desktop/laptop devices with touchscreen, Microsoft Edge also has double-tap to zoom, and any viewport setting has no effect...so in this scenario, touch-action is the only reliable method of suppressing the click delay. Other browsers (Chrome, Firefox, ...) don't seem to (yet) have double-tap to zoom on these platforms...but if they decide to implement it, they'll likely also ignore viewport the same way. So one saving grace of using both mobile viewport and touch-action is the potential future-proofing for this case.

@beyond-code-github
Copy link

I know this is old, but as I came across this page looking for advice I thought I would update.

touch-action: manipulation is still necessary to remove the tap delay in Chrome (and presumably others) on touch screens on Windows 10 laptops such as the Dell XPS 13. https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment