There are legions of faceless hardware and software developers who are owed a debt of gratitude for accomplishing what appears, at first glance, to be a simple transition: equating mouse interactions to touch controls.

The fact that that this transition works so seamlessly is little short of a miracle, allowing interaction models like CSS 3D Origami to respond equally well to fingertip touches or a moving cursor, with no extra coding required.

However, developers cannot cover every eventuality. Inevitably there are situations where a CSS :hover does not translate to touch in the way that you expect or want. In those cases, you will either have to reconsider the interaction model, or code the UI to make it touch-appropriate.

Covering The Basics

In the current deluge of mobile devices, screen width does not indicate that a device has touch capabilities. However, a narrow viewport should motivate a few considerations:

  • Ensure that UI “hit areas” are at least 50px × 50px in size. Small UI elements are difficult to touch accurately.
  • One thumb, one eye. Many visitors will be using your website while moving, distracted, and with only one digit. Ensure that important controls can be reached on the screen with just a thumb.
  • Some delays are difficult to avoid. Right now most mobile platforms have a built-in 300ms latency for web touch events. That ⅓ second delay can really add up for your users. I’ll discuss solutions to this issue in an upcoming article: for now, understand that your UI will not feel as “snappy” on a mobile device for this reason. Reducing or eliminating any transition delays for mobile users is an obvious first step to compensate for this.

Determining If A Device Has Touchability

Accurately detecting touch capability on a device has been made more difficult by IE 10, which erroneously reports touch capabilities even on devices that don’t physically support such actions. The most efficient code I’m aware is the following:

function is_touch_device() {
	return !!('ontouchstart' in window)
		|| !!('onmsgesturechange' in window);
};

As a function, you can call it almost anywhere in your code:

$(document).ready(function() {
	if (is_touch_device()) { 
		// do specific stuff for devices that support touch
	}
})

Managing Touch Events

A touch event will fire several actions, depending on context and platform:

touchstart  → mouseneter → mousedown  → click → mouseup → mouseleave → touchend

The presence and order of the inner actions differ from one platform to the next, and any one of them may mistranslate your :hover or :focus CSS. To cancel the actions entirely, unbind them from elements using JQuery:

$('span.hitmonkey').unbind('mousenter mouseleave touchend touchstart');

In most cases, you don’t need to unbind every action. Instead, you would test to determine which actions are causing issues on particular elements, and unbind those specifically:

$('span.hitmonkey').unbind('touchstart');

This needs to be done carefully, considering the growing number of hybrid devices that offer touch and mouse input: as developers, we cannot anticipate what form an interaction will take. Anything that we unbind should immediately be bound to a solution:

$('span.hitmonkey').bind('touchstart', function() {
	// specific touch-start activity for element, controlled by JavaScript
});

The number of possible solutions is manifold, and impossible to cover in any depth here; I’ll demonstrate specific examples in the next article.

Lots of Touchy-Feely? No Copy-Copy.

If you expect a UI element to receive lots of touch interaction, especially in rapid succession, it’s probably a good idea to disable default double-tap actions. These may include copy (for images), define (for text) or zoom, any one of which will interrupt your user’s experience of the page.

span.hitmonkey {
	-ms-touch-action: none;
	-webkit-touch-callout: none;
	-webkit-user-select: none;
}

Note that this doesn’t cover every mobile browser: you can’t currently control Firefox Mobile or the stock Android browser in regards to double-tap actions.

What About Disabling Zoom Entirely?

It’s possible to disable the user’s ability to zoom the page:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Optionally, you can also add the following, for devices that do not yet support viewport:

<meta name="HandheldFriendly" content="true">

Be aware that disabling zoom is generally ill-advised: among other things, zoom allows those with poor eyesight to read your page.

Conclusion

In general, software translation of hover and click events to touch works surprisingly well. When it doesn’t, solutions are at hand. Physical testing is very important: emulators will not give you the entire experience, necessitating access to a range of devices (and ideally, a device testing lab).

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.