Mobile browser vendors have faced a dilemma for quite a while. They’ve got this double-tap gesture that allows users to zoom in on part of a page (particularly handy on non-responsive sites). But that means that every time a user makes a single tap, the browser has to wait for just a moment to see if it’s followed by another tap. “Just a moment” in this case works out to be somewhere between 300 and 350 milliseconds. So every time a user is trying to click a link or press a button on a web page, there’s a slight but noticeable delay.
For a while, mobile browsers tried to “solve” the problem by removing the delay if the viewport size had been set to non-scalable using a meta viewport
declaration of user-scalable="no"
. In other words, the browser was rewarding bad behaviour: sites that deliberately broke accessibility by removing the ability to zoom were the ones that felt snappier than their accessible counterparts.
Fortunately Android changed their default behaviour. They decided to remove the tap delay for any site that had a meta viewport
declaration of width=device-width
(which is pretty much every responsive website). That still left Apple.
I discussed this a couple of years ago with Tess (my go-to person on the inside of the infinite loop):
She’d prefer a per-element solution rather than a per-document meta element. An attribute? Or maybe a CSS declaration similar to pointer events?
I thought for a minute, and then I spitballed this idea: what if the 300 millisecond delay only applied to non-focusable elements?
After all, the tap delay is only noticeable when you’re trying to tap on a focusable element: links, buttons, form fields. Double tapping tends to happen on text content: divs, paragraphs, sections.
Well, the Webkit team have announced their solution. As well as following Android’s lead and removing the delay for responsive sites, they’ve also provided a way for authors to declare which elements should have the delay removed using the CSS property touch-action
:
Putting
touch-action: manipulation;
on a clickable element makes WebKit consider touches that begin on the element only for the purposes of panning and pinching to zoom. This means WebKit does not consider double-tap gestures on the element, so single taps are dispatched immediately.
So to get the behaviour I was hoping for—no delay on focusable elements—I can add this line to my CSS:
a, button, input, select, textarea, label, summary {
touch-action: manipulation;
}
That ought to do it. I suppose I could also throw [tabindex]:not([tabindex="-1"])
into that list of selectors.
It probably goes without saying, but you shouldn’t do:
* { touch-action: manipulation; }
or:
body { touch-action: manipulation; }
That default behaviour of touch-action: auto
is still what you want on most elements.
Anyway, I’m off to update my CSS even though this latest fix probably won’t land in mobile Safari until, oh ….probably next October.
1 Share
# Shared by Marc Drummond on Saturday, December 26th, 2015 at 4:13am