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.