5

TL;DR version

How to check if the user is on a touch device and/or can hover, using vanilla JavaScript?


Elaborated version

This post here suggest a bazillion different ways to solve this. But it's now 2020 - and a lot has happend across browsers and devices, so I figured I would draw a line in the sand and start a new question. Many of the answers doesn't consider all corner cases:

  • Like stylus'es
  • Like Apple's magic mouse that (apparently) emulated touch events (I heard of this, I haven't experienced it myself).
  • Like the new iPad Pro, which emulates a Macbook Pro's Safari.
  • Like if the capability changes, so the user gains/loses the ability to 'touch' (Like when enabling mobile-view with Chrome Developer tools).

My findings

Don't use window.matchMedia('(any-pointer: XXXXX)').matches

Some answers suggested the 'new and fancy' window.matchMedia with any-pointer: coarse|none|fine. However, - I was in luck that I have an OnePlus 5t. Because that matchMedia didn't work in neither Firefox nor Chrome on my device (false matching). I played around with the A TON, since I would love to have the same CSS-check, so my JavaScript and my CSS corresponded with one-another, ensuring that styles and functionality matched.

Don't use userAgent matching

It's not a good idea, since it would require maintaining the userAgent list, every time a new browser comes out. So it's not future-proof to do it this way. Like the iPad Pro-example mentioned earlier.

Don't use human touch

This Code Burst article suggests using human touch instead of detecting device touch. That may be part of the solution. But if I have a menu for touch-users, then I will have to display that straight away, instead of waiting for the user to touch the screen before showing it.

Zeth
  • 2,273
  • 4
  • 43
  • 91

1 Answers1

9

I made a CodePen, that is setup ready to add new functions, and test i easily. It also shows the best solution I've found so far: https://codepen.io/zethzeth/pen/yLewqbg

I'm not sure what to do about stylus'es or other wierd cases.

Here's the function:

function is_touch_device4(){
  return window.matchMedia('(hover: none)').matches;
}
Zeth
  • 2,273
  • 4
  • 43
  • 91