Media query to detect if device is touchscreen
Nowadays, CSS Media queries can be used to define style for devices with specific interactive features and it's widely supported as well.
hover for example can be used to test whether the user's primary input mechanism can hover over elements (which would not be true in touch-enabled devices without emulating)
@media (hover: none) {
a {
background: yellow;
}
}
Other interactive tests are: pointer, any-pointer, hover, and any-hover
Previous answer
I would suggest using modernizr and using its media query features.
if (Modernizr.touch){
// bind to touchstart, touchmove, etc. and watch `event.streamId`
} else {
// bind to normal click, mousemove, etc.
}
However, using CSS, there are pseudo class like, for example in Firefox. You can use :-moz-system-metric(touch-enabled). But these features are not available for every browser.
For Apple devices, you can simply use:
if (TouchEvent) {
//...
}
Especially for iPad:
if (Touch) {
// ...
}
But, these do not work on Android.
Modernizr gives feature detection abilities, and detecting features is
a good way to code, rather than coding on basis of browsers.
Styling Touch Elements
Modernizer adds classes to the HTML tag for this exact purpose. In this case, touch
and no-touch
so you can style your touch related aspects by prefixing your selectors with .touch. e.g. .touch .your-container
. Credits: Ben Swinburne
How to write CSS media queries to detect a touchscreen device?
I want to use CSS to detect if my user uses a touch input.
In 2019, pretty much all browsers can now understand interaction @media queries
:
@media only screen and (hover: none) {
[... CSS HERE...]
}
indicates that the primary interaction method is not a mouse-pointer (or similar device with hover capability).
This usually means that the primary interaction method is touch.
Browser compatibility
https://caniuse.com/#feat=css-media-interaction
How to detect touch device in 2019?
This is really simple with just one line of code:
const touch = matchMedia('(hover: none)').matches;
- What? matchMedia
?
- This is just a JS API to do CSS @media queries. And it is supported in modern browsers: https://caniuse.com/#feat=matchmedia. Of course, you may use such queries directly in CSS:
@media (hover: none){
/* touch stuff goes here */
}
- Ok, what @media queries may be also useful?
@media (hover: none) and (pointer: coarse) {
/* touchscreens */
}
@media (hover: none) and (pointer: fine) {
/* stylus */
}
@media (hover: hover) and (pointer: coarse) {
/* controllers */
}
@media (hover: hover) and (pointer: fine) {
/* mouse or touchpad */
}
But this will query only the primary input method. If you want to go deeper, you may use any-hover
and any-pointer
to query all input devices.
UPD: hack for old browsers removed, seems like most old browsers does not support hover
and pointer
media queries too. You may use touch event detection and touch-only navigator
properties from another answers
UPD2: In your case, it's preferable to use
const touch = matchMedia('(hover: none), (pointer: coarse)').matches;
What's the best way to detect a 'touch screen' device using JavaScript?
Update: Please read blmstr's answer below before pulling a whole feature detection library into your project. Detecting actual touch support is more complex, and Modernizr only covers a basic use case.
Modernizr is a great, lightweight way to do all kinds of feature detection on any site.
It simply adds classes to the html element for each feature.
You can then target those features easily in CSS and JS. For example:
html.touch div {
width: 480px;
}
html.no-touch div {
width: auto;
}
And Javascript (jQuery example):
$('html.touch #popup').hide();
mediaquery : How to detect touch device?
There isn't a media query to detect touch devices. You would need to use something like Modernizer.
Media Query: Touch Only
Yes there is reason not to: orientation
is unrelated to whether the device uses touch, it uses viewport width and height to esablish what the orientation is. (orientation: landscape)
will apply when the viewport is wider than it is tall and (orientation: portrait)
will apply when the viewport is taller than it is wide. So in effect, any browser on any device that supports media queries fully will utilise orientation
.
Check out the jsfiddle form this stackoverflow answer and you'll see the orientation media query taking effect when you resize your browser window.
As an addendum, you should be aware of this quote from the modernizr docs:
The Modernizr.touch test only indicates if the browser supports touch
events, which does not necessarily reflect a touchscreen device. For
example, Palm Pre / WebOS (touch) phones do not support touch events
and thus fail this test. Additionally, Chrome (desktop) used to lie
about its support on this, but that has since been rectified.
Modernizr also tests for Multitouch Support via a media query, which
is how Firefox 4 exposes that for Windows 7 tablets.From http://modernizr.com/docs/#features-misc
Having said that, it may still be suitable for what you're doing. That's up to you
Detect if a browser in a mobile device (iOS/Android phone/tablet) is used
Update (June 2016): I now try to support touch and mouse input on every resolution, since the device landscape is slowly blurring the lines between what things are and aren't touch devices. iPad Pros are touch-only with the resolution of a 13" laptop. Windows laptops now frequently come with touch screens.
Other similar SO answers (see other answer on this question) might have different ways to try to figure out what sort of device the user is using, but none of them are fool-proof. I encourage you to check those answers out if you absolutely need to try to determine the device.
iPhones, for one, ignore the handheld
query (Source). And I wouldn't be surprised if other smartphones do, too, for similar reasons.
The current best way that I use to detect a mobile device is to know its width and use the corresponding media query to catch it. That link there lists some popular ones. A quick Google search would yield you any others you might need, I'm sure.
For more iPhone-specific ones (such as Retina display), check out that first link I posted.
Related Topics
What Are the Rules For CSS Media Query Overlap
Simulating Transform-Origin Using Translate
What's the Difference Between CSS Classes .Foo.Bar (Without Space) and .Foo .Bar (With Space)
Why Doesn't the CSS Calc() Function Work For Me
Sass Invalid CSS Error: "Expected Expression"
How to Only Show Certain Parts with CSS for Print
Differencebetween Align-Items VS. Align-Content in Grid Layout
CSS Rotate a Pseudo :After or :Before Content:""
What Has Bigger Priority: Opacity or Z-Index in Browsers
Css: Margin-Top When Parent'S Got No Border
Twitter Bootstrap Form File Element Upload Button
Dynamically Change Color to Lighter or Darker by Percentage Css
Bootstrap Icons Are Loaded Locally But Not When Online
How to Have Css3 Animation to Loop Forever