Detecting that the browser has no mouse and is touch-only
css, html, javascript, mouse, touch
Solution
As of 2018 there is a good and reliable way to detect if a browser has a mouse (or similar input device): CSS4 media interaction features which are now supported by almost any modern browser (except IE 11 and special mobile browsers).
W3C:
The pointer media feature is used to query the presence and accuracy of a pointing device such as a mouse.
See the following options:
/* The primary input mechanism of the device includes a
pointing device of limited accuracy. */
@media (pointer: coarse) { ... }
/* The primary input mechanism of the device
includes an accurate pointing device. */
@media (pointer: fine) { ... }
/* The primary input mechanism of the
device does not include a pointing device. */
@media (pointer: none) { ... }
/* Primary input mechanism system can
hover over elements with ease */
@media (hover: hover) { ... }
/* Primary input mechanism cannot hover
at all or cannot conveniently hover
(e.g., many mobile devices emulate hovering
when the user performs an inconvenient long tap),
or there is no primary pointing input mechanism */
@media (hover: none) { ... }
/* One or more available input mechanism(s)
can hover over elements with ease */
@media (any-hover: hover) { ... }
/* One or more available input mechanism(s) cannot
hover (or there are no pointing input mechanisms) */
@media (any-hover: none) { ... }
Media queries can also be used in JS:
if(window.matchMedia("(any-hover: none)").matches) {
// do something
}
Related:
W3 documentation: https://www.w3.org/TR/mediaqueries-4/#mf-interaction
Browser support: https://caniuse.com/#search=media%20features
Similar problem: Detect if a client device supports :hover and :focus states
Problem
I'm developing a webapp (not a website with pages of interesting text) with a very different interface for touch (your finger hides the screen when you click) and mouse (relies heavily on hover preview). How can I detect that my user has no mouse to present him the right interface? I plan to leave a switch for people with both mouse and touch (like some notebooks). The touch event capability in the browser doesn't actually mean the user is using a touch device (for example, Modernizr doesn't cut it). The code that correctly answers the question should return false if the device has a mouse, true otherwise. For devices with mouse and touch, it should return false (not touch only) As a side note, my touch interface might also be suitable for keyboard-only devices, so it's more the lack of mouse I'm looking to detect. To make the need more clear, here is the API that I'm looking to implement: ``` // Level 1 // The current answers provide a way to do that. hasTouch(); // Returns true if a mouse is expected. // Note: as explained by the OP, this is not !hasTouch() // I don't think we have this in the answers already, that why I offer a bounty hasMouse(); // Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking) // callback is called when the result of "hasTouch()" changes. listenHasTouchChanges(callback); // callback is called when the result of "hasMouse()" changes. listenHasMouseChanges(callback); ```
Related problems
- jQuery: Detecting pressed mouse button during mousemove event
- What's the best way to detect a 'touch screen' device using JavaScript?
- Is it possible to use javascript to detect if a screen reader is running on a users machine?
- Detect if a client device supports :hover and :focus states
- Detect whether browser has keyboard/arrow keys in web page