Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Modernizr.touch detects touch events not touch devices #548

Closed
paulirish opened this Issue · 40 comments

9 participants

@paulirish
Owner

IE Mobile e.g. doesnt expose webkit touch events but is a touch device..

what exactly does Modernizr.touch imply? We should agree so we can document it.

@ryanseddon
Owner

Yes, yes we should. Caniuse.com says Firefox 9+ supports touch but our test says otherwise when comparing to caniuse.com results.

@dmethvin

I think there is already way too much code around that expects Modernizr.touch to mean Webkit touch events. If Firefox does a good enough job of emulating them then it seems it should be true there too. Microsoft's touch events are [http://blogs.msdn.com/b/ie/archive/2011/09/20/touch-input-for-ie10-and-metro-style-apps.aspx completely different] so I think it would be better to define Modernizr.pointer or Modernizr.mspointer for them.

@paulirish
Owner

I like dave's proposal.

We tried capturing firefox touch in the Modernizr.touch test and it led to bad code forking.
We need to test and expose each unique touch model, however ridiculous that is.

see also jquery's upcoming blog post.

@dmethvin

Yes, I am afraid there are dark days ahead when it comes to apps handling touch events. The Webkit model would have been fine with me but it seems unlikely to gain a W3C blessing now. We can blame Apple's foot-dragging for this fragmentation.

@ryanseddon
Owner

Yep this will be good to breakout touch into a plugin since it'll get huge testing for all variants.

I'm pretty sure caniuse.com is wrong when it says firefox supports touch I have been poking around fennec and it doesn't support touch and they deprecated their MozTouch in 4.0

@lauripiispanen

ref #448 - I agree with the second point of optimizing the layout with media queries. Any sufficiently small screen can be handled with those.

But in any case, windows phones currently don't send any events whatsoever (not even MSPointerEvents, they are slated for later versions), so you would need to detect that and render e.g. clickable controls vs swipeable ones. So for the current breed of windows phones, "touch" being true is valid in that the input method is a touch one and you need bigger manipulation controls for the user to hit. Then again, "touch" being false is valid in that the browser doesn't send any meaningful information whatsoever on the user's touch input.

@paulirish
Owner

So there is

  • Event model detection: so i can fork my JS event binding code to do the right thing
  • Touch device detection: so i can optimize my layout and interaction for fingers.

I think media queries tackle the second, for now... but so shall we just focus on touch event models?

@lauripiispanen

I agree that's a good strategy. Having Modernirz.touch return the applicable touch event model, and null/false if no touch event model is present should be enough cue to add non-touch manipulable controls on the page.

@paulirish
Owner
Modernizr.touch // 'apple'
Modernizr.touch // 'pointer'
Modernizr.touch // false

How about that?

@dmethvin

Should that be 'webkit'?

Do we have an idea how people are using Modernizr.touch as far as its implications? I would bet a lot of it today expects it to mean Webkit touch events and would break otherwise.

@ryanseddon
Owner

@dmethvin yeah very good point that's how a lot of people would be using it. Not sure how we could handle it, the docs clearly state that it will return true in situtations where it's not a touchscreen device but does support touch.

@paulirish
Owner

related tickets:

  • #372 Non-touch BlackBerry devices return false positive for Modernizr.touch
  • #448 Modernizr.touch == false on Windows Phone
  • #220 False positive at touch events on Nokia N900 (Maemo)
  • #339 Lenovo Thinkpad T400 should not be a 'touch' device
@masteroleary

Yikes, this is too complicated for me. Props to you all.

@paulirish
Owner

Related: http://code.google.com/p/chromium/issues/detail?id=152149

worth reading:

At the moment (to avoid broadly breaking sites like you describe) touch event support is enabled dynamically at run-time when we detect a touch screen. So any site that assumes that touch event support implies a mobile device (or lack of mouse support generally) will be broken on Windows/ChromeOS with a touch screen. Also, mobile devices like blackberry (and to a lesser extent Android) support mice in addition to a touch screen - so it's never really been true that touch event support implies you can ignore mouse events.

Also, I believe you're conflating the concept of "the browser supports touch events" and "the user has a touch screen". Just because there is currently no touch screen on a device, doesn't mean chrome shouldn't support touch events. See issue 159527 for more discussion.

Obviously we have a long way to go to make it standard practice and easy for websites to support touch events on desktop devices, but with the rise in popularity of touchscreen laptops (eg. with Win8) this is going to be an important area of focus.

@paulirish
Owner

Confirmation that the Chrome team added support for pointer and hover media queries to webkit and enabled Chromium to appropriately enable them when it discovers a touch screen. It's either now (or very soon) available in desktop Chrome (Windows 8 in particular), and Chrome for Android.

It's worth pointing out some gotchas:

  • a touch screen could be dynamically be added via a KVM
  • there are an increasing number of scenarios where there is both a touch screen and a pointing device.

To avoid confusion, I expect us to deprecate Modernizr.touch as people will consider it as "touch device". We will introduce something like Modernizr.touchevents and Modernizr.touchevents.w3c & Modernizr.touchevents.pointer

@paulirish
Owner

As for pointer/hover media queries.. each WebKit port needs to enable them individually-- the embedding environment needs to inform webkit what hardware the device has.. As such, it's possible the next releases of Blackberry, Nokia, iOS, and other webkit ports may not have these media queries enabled yet. If you have friends there, make sure they know you want them. :)

@ryanseddon
Owner

So would Modernizr.touchevents.pointer indicate a true on the coarse MQ? And would the top level Modernizr.touchevents indicate it supports either the w3c events or pointer coarse?

@paulirish
Owner
@stucox
Owner

Thanks for these updates @paulirish.

Does it really make sense for a pointer detect to fall under Modernizr.touchevents though? The whole point of the PointerEvent spec is it's independent of touch, mouse, etc.

Wouldn't simply Modernizr.touchevents and Modernizr.pointerevents be cleaner and more suitable?

Hopefully Kinect-style motion sensing input devices would fire PointerEvents too, but by definition don't involve touching anything!


Also, none/fine/coarse values from the media query is a feature of the device again, not the browser. It's also a dynamic feature - as devices may be plugged/unplugged - where as Modernizr is "static" in that it's just run on page load.

My opinion would be that Modernizr should stick to detecting static browser support for PointerEvents and TouchEvents, while media queries can be used to determine, dynamically, whether or not a certain input device capability is present. So no need for Modernizr.coarsepointer or similar.

Encouraging this pattern would (eventually) mean browsers no longer have to enable/disable touch-related APIs at runtime based on the input devices connected, and would encourage developers to consider input modes as a dynamic feature, like we already do for screen size.

I love the idea of opening a web page on a tablet at home, using a mouse & keyboard with it, unplugging it to head out the door and the UI automatically switching to a touch-friendly variant.

@paulirish
Owner
@dmethvin

Encouraging this pattern would (eventually) mean browsers no longer have to enable/disable touch-related APIs at runtime based on the input devices connected, and would encourage developers to consider input modes as a dynamic feature, like we already do for screen size.

:cake:

Pointer choices should just be considered part of a responsive design.

@ryanseddon
Owner

@stucox well said and I agree with everything. :metal:

@KuraFire
Owner

I agree with everything @stucox suggested as well. Modernizr.touchevents and Modernizr.pointerevents is a good solution for this finicky issue. And keeping Modernizr itself focused on static feature detection, rather than dynamic changes, works for me.

@stucox
Owner

Slight problem with the plan above: we already have Modernizr.pointerevents for the CSS pointer-events property.

So... Modernizr.domtouchevents and Modernizr.dompointerevents? Or just dompointerevents and leave touchevents?

@paulirish
Owner
@stucox
Owner

Yep. Incoming major version number... now's as good a time as any to tidy things like this up.

@ryanseddon
Owner

I'd go for breaking css pointer-events maybe even have a console.warn?

@stucox
Owner

console.warn on... Modernizr.pointerevents? Not sure if I like giving a warning to people who are using the new API - highly annoying to the many, for the benefit for the few who didn't read the release notes; very few if the CSS pointer-events test is indeed rarely used.

@dmethvin

for the benefit for the few who didn't read the release notes

:crying_cat_face: Why can't jQuery users be avid readers like Modernizr users? :wink:

But seriously, i like re-purposing the name since I suspect it will be much more commonly used. Maybe we can lobby to get the CSS pointer events renamed.

@ryanseddon
Owner

yeah ok probably not my best idea lets just make it bold in release notes that pointer-events means something else now.

@stucox stucox was assigned
@stucox
Owner

I'll put together a PR for this. Has anyone made a start on any 3.0 release notes yet?

@paulirish
Owner
@nathggns

So what is the recommended way to detect touch now?

@stucox
Owner

You can't reliably. Alternative approaches depend on your use case — but this HTML5 Rocks article is well worth a read.

@dmethvin

After all that was said, you got to the bottom and used a vague term like "detect touch". You'll need to be more specific. Detect the potential for the device to generate WebKit touch events? Detect the ability to generate Microsoft pointer events? Detect a device capable of generating any sort of events when its screen is touched, without regard for how it's exposed in JavaScript? Detect a touch-capable device that (currently or eternally) has no other means of interaction such as a mouse or physical keyboard? The info in #869 may be helpful and #805 mentions the new touchevents vs pointerevents split.

@nathggns
@stucox
Owner

The details of the input mechanisms simply aren't currently made available to apps running in the browser.

So "assume nothing" tends to be the best advice at the moment. As well as the HTML5 Rocks article, this is worth a read: http://globalmoxie.com/blog/desktop-touch-design.shtml.

@stucox
Owner

Btw, we've got a note in #805 to document the touch -> touchevents / pointerevents change, so I think we can close this.

@nathggns - feel free to open a new issue to discuss this more.

@stucox stucox closed this
@kuus

It of course depends on lot of cases, but I found handy the following checks (n addition to Modernizr) to force the no-touch beahvior:

if {( 
        (window.location.host == 'apps.facebook.com') || // in the facebook app it's difficult to manage media queries (cause of the sidebar) so in desktop devices with touch screen it's tricky
        (window.screen.width > 1279 && window.devicePixelRatio == 1) || // this number could be probably 1281, there are no so many mobile devices with more than 1280 and pixelRatio equal to 1 (i.e. retina displays are equal to 2...)
        (window.screen.width > 1000 && window.innerWidth < (window.screen.width * .9)) || // this checks in the end if a user is using a resized browser window which is not common on mobile devices
        (window.screen.width > 1000 && !this.browser.mobile) // this.browser.mobile is a custom check that can use for instance a common jquery plugin for browser detection
    ) {
        // then add a class to html
        $('html').addClass('force-no-touch');
    }

then in the css applying the .no-touch class (modernizr), together with the custom .force-no-touch class

@bjjb bjjb referenced this issue from a commit in bjjb/sceitse
@bjjb bjjb Mobile version
Lets you draw with touches. There's also a manifest.webapp for open web apps
(such as for Firefox OS). Modernizr is used for detecting whether the device
supports touches, but this is _not_ 100% reliable, yet:

Modernizr/Modernizr#548

Currently, the points are 15px off on the Y axis.
db4f646
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.