Create a gist now

Instantly share code, notes, and snippets.

@gajus /README.md
Last active Nov 29, 2016

What would you like to do?

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

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
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

@simevidas

@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

@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

@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

Awesome. Thanks a lot for sharing this GIST.

@simevidas

@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

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
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
Itrulia commented Feb 24, 2016

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

@simevidas

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

@Itrulia
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

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

@patrickhlauke

@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.

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