Touch Me, I Dare You…

Touch me I dare you This week I’m at JSConf and had the pleasure of speaking. The title of my talk was Touch Me, I Dare You. It’s the first talk that I’ve done since I joined Internet Explorer. One of the big things that we’re working on in Internet Explorer is touch. We think that it’s an incredibly important part of life on the web going forward. Why does touch matterThere’s a lot of reasons that we think that. One of the reasons that we think that is that is that we’re looking at the incredible proliferation of touch devices out there in the world. This ranges from all of the smart phones out there to the tablets to the laptops and convertibles that have touch screens as well. It’s a growth space for sure. Touch has reached into almost every aspect of our lives. There’s even a touch screen TV with an interactive display just off the lobby in the hotel here at the conference.

What's your strategy for dealing with touch?

So what’s your strategy for dealing with touch? The first possible strategy is to just simply ignore touch and let the defaults take care of things. If you do that, the browser will treat your finger as a mildly inaccurate mouse. This is a legitimate strategy as long as it’s your strategy and you do it deliberately and take on board some of the other best practices which I’ll talk about in a moment. The second strategy is to retrofit touch support onto your web site. This is a loosing strategy every time. It’s much better to work the other way around and design for touch first. This ensures that you’ve taken the best practices into account typically mouse and keyboard just work at that point.

Hover sucks

The first of the best practices is that hover sucks, don’t use it. The key to touch is that it’s touching. The screen has no idea that your finger is a millimeter from the screen. Some of the browsers will help you and make the touch emulate a hover but it’s not a great experience. Even with a mouse actually, hover still sucks because it’s not a natural motion to try and stay over your content even if it’s not a straight line in order to keep the menu open. If you don’t believe me, try it sometime and think about the users that keep loosing the menu when trying to move from the top to a sub menu.

Touch sized buttons

Hopefully obviously, you need to use touch sized buttons. It’s a great thing that a lot of devices, especially smart phones, allow you to zoom in in really easily into your different controls and interactions but this is not fun. The ideal way to do this to build for touch first and everything that you do here will actually make your mouse and other inputs work better.

Demo of different size fingers The reality is that the finger is much wider than a mouse. How wide? Depends. An NBA player has a finger that’s kinda in the 20mm width range. That’s a big finger and he’s not going to be able to use your site on his touch device. Normal is closer to 11mm which works out to roughly 42px depending on the size, resolution and pixel density of your screen.

Ergonomics & touch

And with touch more than any other type of input, you need to keep your user’s context in mind. They could be walking, holding the device on their lap, on a train, in a stand on a desk like a normal monitor or any other type of context. All of these contexts mean that accuracy might or might not be incredibly accurate. You should design with large targets with plenty of breathing room to help with that. It’s also important to give visual and potentially audio feedback on touch to let people know that something actually happened.

how far to fingers reach on a tablet

Also for touch, you have to think about how long a finger is and how comfortable it is to reach different points on the screen. You can check this yourself on your own touch device. Reaching things in the top center of the screen is tough whereas on the sides and the bottom is a lot easier.

Design for touch first

The natural reading areas are at the top center of the screen. This is true regardless of what type of input you are using because that’s where the eye goes.

 

Remember there's more than one finger

Another thing that is incredibly important to remember is that there’s more than one finger that they could be playing with. It’s actually very possible that two people will be touching your site at the same time. This is in stark contrast to a mouse as there’s only one on the screen at any point in time.

remember there's more than one kind of input

The other thing to realize is that there’s very potentially more than one type of input happening at any given time. People can use mouse, touch and pen input all at the same time. It’s important to keep this in mind and build for that from the beginning.

So how to I do all that?

That sounds like a lot of stuff. So how do I do that in the simplest way possible. One of the issues with a lot of current code is that it will work for either touch or mouse. Or it will ignore pen input. The reality is that we can, with one simple set of events, manage for all of that.

Go Pointers

With IE10, we implemented a new interaction model called Pointer Events. It’s currently implemented as a MS prefixed set of events in just IE10 but we’ve submitted it as a spec to the W3C. The reception from the W3C and surrounding community has been outstanding. It made it from submission to Candidate Recommendations in a fairly blazing 9 months. We’ve been working with a lot of other browser vendors and we’re looking forward to some wide spread adoption.

W3C Pointer StandardThe event model is fairly similar to what you’d see with your mouse but the events you catch are much richer.

The events are pointerdown, pointerup, pointermove, pointerover, pointerout and pointercancel. I made the mistake in the slides of upper casing the second word in each of the events.

Pointer Event Models

At the moment, in IE10, the events are MS prefixed and you should use those in IE10. We’ll talk about support for other browsers in a moment.

 

 

Values on the events include width, height, pressure, tilt, rotation, and more

On each of the events, you get width, height, pressure, tilt, rotation, pointerType (mouse, touch, pen…), event type and more. The great news here is that

 

 

Coding for multi-touch

Coding for multi-touch is actually pretty simple. Each time you get one of the events, you should iterate through the list of current pointers and react to each of them appropriately. This is the primary difference that you’ll have to make to move from mouse and interacting with one item on your page to more than one and interacting with multiple items on your page. Gestures and the like were not something that I discussed primarily because it’s a complex subject and I only had a short 30 minutes.

current touch support on IOS/Android

Current touch support on IOS and some android devices is based on the Apple recommendation of touchstart, touchmove and touchend. There are a couple of issues with this approach. Sidestepping the politics and focusing on the technical, touchstart handles exactly what it says – touch. It doesn’t handle mouse or pen so you have to code separate paths for each.

Touch first coding With pointer events, you only have to code for one thing if the browser supports pointer events but you will have to polyfill on the browsers other than IE10 at the moment. You can do this by hand by just doing a fallback to touchstart and mouse. There’s actually an unintentional bug in the code sample in my slide. I do the pointer event but in the fallback, I only catch touch OR mouse, not both which means that someone with a touch screen won’t be able to use a mouse.

Use polyfills for older browsers

Regardless, it’s much better to use one of the polyfill libraries such as hand.js from Bitovi. I still like to default to the MSPointer events in IE10 because they are native and then polyfill the other browsers where needed at the moment.

 

 

if (window.navigator.msPointerEnabled) {
	
	// MSPointer events which are only in IE10. Use if possible as they are native
	Event(leftOverlay, "MSPointerUp", function() { 
		if(Game.canStart()) { Balls.release(Player.ONE); } }, false);
	
	Event(rightOverlay, "MSPointerUp", function() { 
		if(Game.canStart()) { Balls.release(Player.TWO); } }, false);
	
	Event(leftOverlay, "MSPointerMove", Game.movePaddle, false);
	
	Event(rightOverlay, "MSPointerMove", Game.movePaddle, false);

}

else
{
	
	// these are the polyfill events for hand.js. Use these as a backup currently
	
	// as these are the polyfill.
	
	Event(leftOverlay, "pointerup", function() { 
		if(Game.canStart()) { Balls.release(Player.ONE); } }, false);
	
	Event(rightOverlay, "pointerup", function() { 
		if(Game.canStart()) { Balls.release(Player.TWO); } }, false);
	
	Event(leftOverlay, "pointermove", Game.movePaddle, false);
	
	Event(rightOverlay, "pointermove", Game.movePaddle, false);

}		

wrapup

Hopefully this has been helpful. There’s a lot more that I didn’t get a chance to cover that can be found at http://modern.ie as well as http://docs.webplatform.org/PointerEvents. And as always, you can find me on http://twitter.com/joshholmes.

BTW – the slides are up at http://www.slideshare.net/joshholmes/touch-me-22254401 

Good luck and go touch something…