84

Is there a way to detect if a handheld browser is used (iOS/Android phone/tablet)?

I tried this with the goal to make an element half as wide in a browser on a handheld device but it doesn't make a difference.

width: 600px;
@media handheld { width: 300px; }

Can it be done and if so how?

edit: From the referred page in jmaes' answer I used

@media only screen and (max-device-width: 480px).

ivvi
  • 5,120
  • 5
  • 36
  • 53
  • 2
    Is the goal detecting any mobile devices, or do you need to be able to distinguish between handheld devices and tablets? – Matt Coughlin Feb 18 '13 at 18:09
  • 1
    The goal is to detect any mobile device. – ivvi Feb 18 '13 at 19:47
  • 2
    To detect if touch screen: http://stackoverflow.com/questions/11387805/touchscreen-media-queries , orientation change: http://stackoverflow.com/questions/13803838/detecting-if-a-device-is-able-to-change-orientation-in-javascript/13805337#13805337 – Ciro Santilli OurBigBook.com Nov 18 '14 at 14:24

11 Answers11

58

Here's how I did it:

@media (pointer:none), (pointer:coarse) {
}

Based on https://stackoverflow.com/a/42835826/1365066

GrayFace
  • 1,224
  • 10
  • 13
  • 2
    doesn't always work. I'm using a Lenovo Yoga 2 Pro (touchscreen), external full hd monitor, Win10 1803. on Firefox 62: works (div is green), on Chrome 69: it doesn't (div is red) so again just trying to get a lucky punch with this workaround :/ – themenace Sep 14 '18 at 08:20
  • Clever solution! – Felipe Mar 25 '20 at 22:30
  • It is hard to debug with this rule. If you plan to use this with a desktop browser and mobile view, selecting pointer on the element will un trigger any styles proposed for mobile view. – kalle Jul 13 '21 at 10:41
44

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.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
jamesplease
  • 12,547
  • 6
  • 47
  • 73
  • 10
    No, as devices today have the same or even higher resolution than desktop monitors, screen resolution is not the best way. – NaN Jun 17 '16 at 11:57
  • 3
    @EASI Even though device screens may have more pixels than desktop today, they are decreased to "CSS size" through "pixel ratio", i.e. the size reported and used in CSS and media queries is `n` times lower than physical pixel size (with `n` being 1, 2, 3…) E.g. see http://www.mydevice.io/devices/ Of course media queries using screen size to detect device type is cumbersome, but there is not so many other options around unfortunately… – ghybs Feb 03 '17 at 10:52
  • According to https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries, the list you provided is using the no-longer-guaranteed-to-work `device-width` and `device-height` media features – Caleb Jay May 14 '18 at 20:18
  • 1
    @CalebJay True, but first, the very reliable CSS tricks site still shows that webkit method as valid in many devices, including Iphone-10 and many new Galaxy phones! (https://css-tricks.com/snippets/css/media-queries-for-standard-devices/). But more important, the so called "more standard" "pixel ratio" does not seem to work in the iphones I've tried. So it would seem that if (as i do) you REALLY need to make some display compensations for the mobile cases, the webkit method is a Godsend! That is, of course, until it isn't :-( – Randy Jan 06 '19 at 23:34
14

Don't detect mobile devices, go for stationary ones instead.

Nowadays (2016) there is a way to detect dots per inch/cm/px that seems to work in most modern browsers (see http://caniuse.com/#feat=css-media-resolution). I needed a method to distinguish between a relatively small screen, orientation didn't matter, and a stationary computer monitor.

Because many mobile browsers don't support this, one can write the general css code for all cases and use this exception for large screens:

@media (max-resolution: 1dppx) {
    /* ... */
}

Both Windows XP and 7 have the default setting of 1 dot per pixel (or 96dpi). I don't know about other operating systems, but this works really well for my needs.

Edit: dppx doesn't seem to work in Internet Explorer.. use (96)dpi instead.

LGT
  • 4,957
  • 1
  • 21
  • 22
10

Detecting mobile devices

Related answer: https://stackoverflow.com/a/13805337/1306809

There's no single approach that's truly foolproof. The best bet is to mix and match a variety of tricks as needed, to increase the chances of successfully detecting a wider range of handheld devices. See the link above for a few different options.

Community
  • 1
  • 1
Matt Coughlin
  • 18,666
  • 3
  • 46
  • 59
  • 2
    Haha, how bizarre that we can't detect if the user has a touchscreen or not! – Kokodoko Jun 02 '16 at 16:40
  • 1
    @Kokodoko yeah, it does seem bizarre. To make matters more interesting, some new Windows laptops are traditional computers with touchscreens. Other devices have high resolution and are touch-screen only, like the larger iPad Pro. I'd say the best practice today is to support everything on every resolution. – jamesplease Jun 17 '16 at 23:04
7

I believe that a much more reliable way to detect mobile devices is to look at the navigator.userAgent string. For example, on my iPhone the user agent string is:

Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.0 Mobile/14F89 Safari/602.1

Note that this string contains two telltale keywords: iPhone and Mobile. Other user agent strings for devices that I don't have are provided at:

https://deviceatlas.com/blog/list-of-user-agent-strings

Using this string, I set a JavaScript Boolean variable bMobile on my website to either true or false using the following code:

var bMobile =   // will be true if running on a mobile device
  navigator.userAgent.indexOf( "Mobile" ) !== -1 || 
  navigator.userAgent.indexOf( "iPhone" ) !== -1 || 
  navigator.userAgent.indexOf( "Android" ) !== -1 || 
  navigator.userAgent.indexOf( "Windows Phone" ) !== -1 ;
Jesse Heines
  • 121
  • 2
  • 4
  • 1
    This will work OK... if you only care about iPhone, Android and Windows Phone. But there are entire other device classes out there e.g. don't forget Blackberry and Opera Mini users. Opera Mini alone accounts for some 350m users. Also, older feature phone users won't match these patterns either and these are the very devices that absolutely need a mobile-specific experience. The ugly reality is that this area has gotten complex enough that simple solutions no longer work. – Ronan Cremin Jun 26 '17 at 14:58
  • 2
    Yes, you are of course correct, @RonanCremin, but you can add any other user agent string keywords that you like. (And I realize that my code could be made more efficient using a regular expression.) I also agree that such situations are often more complex than they first appear. – Jesse Heines Jun 27 '17 at 19:17
  • You could also use `.contains()` instead of `.indexOf() !== -1` to make it a little cleaner. – coppereyecat Oct 17 '22 at 21:44
  • I think you mean .includes(), don't you. I don't think that there is a .contains() method in plain JavaScript, but I see that there is such a method in Node.js. – Jesse Heines Oct 18 '22 at 22:38
5

Hello,

I know this question is too old but still the detection of touch screen is so complicated even in 2022 as of my knowledge. However its not impossible to detect since there are different ways of detecting if a device is using touch screen or not.

Here is the solution using 2 different methods which are CSS and JavaScript:

1-The solution using css:

/* if device has a touch screen */
@media (any-pointer: coarse) {
    /* do your own styles */
    .yourDiv:active {
        background-color:red; 
    }
}

/* if device has no touch screen */
    @media (any-pointer: fine) {
        /* do your own styles */
        .yourDiv:active {
            background-color:green; 
        }
    }

Important note:
For the code to work on all devices:

  • You must use any-pointer ✔️
  • Do not use only pointer ❌

2-The solution using JavaScript:

/* returns a true value if device has a touch screen no matter what 
type of device it is */ 
var isTouchScreen = 'ontouchstart' in window || navigator.msMaxTouchPoints;

if(isTouchScreen === true) {
alert("You are using a touch screen")
} else {
 alert("You are not using a touch screen")
}

Conclusion:

The above codes work on almost all type of devices and browsers(not very old versions), if you have a device or an old browser that does not work with those solutions then you need to do a specific code for it in addition to this one.

Adam John
  • 51
  • 1
  • 5
3

Many mobile devices have resolutions so high that it's hard to distinguish between them and much larger screens. There are two ways to deal with this problem:

Use the following HTML code to scale the pixels (grouping smaller pixels into groups the size of the unit pixel - 96dpi, so px units will have the same physical size on all screens). Note that this will affect the scale of pretty much everything in your website, but this is generally the way to go when making sites mobile-friendly.

<meta name="viewport" content="width=device-width, initial-scale=1">

Alternatively, measuring the screen width in @media queries using cm instead of px units can tell you if you're dealing with a physically small screen regardless of resolution.

potato
  • 995
  • 11
  • 19
  • This needs a ton more up votes! Measuring display width using pixels doesn't make sense anymore. Modern flagship handheld phones have more horizontal pixels than my 1080p computer monitor and take up 1/6th of the width. – CausingUnderflowsEverywhere Apr 27 '23 at 21:51
1

I would probably opt for a JS-based approach instead since there does not seem to be a reliable/uniform way of doing this with pure css.

You could use javascript to make your detection - Illustrated here: What is the best way to detect a mobile device?

Then you could simply add something like this to your clientside code:

  $("div").addClass("Mobile-Based-Class");
Bonez024
  • 1,365
  • 1
  • 13
  • 21
0

CSS Level 5 Media Queries are best for this

below code styles css for touch screen devices except old androids and windows touch screens because windows touch screens are hover-able devices with mouse pointer...

@media (hover: none) { /* css for touch screen devices except old androids and windows touch screens because windows touch screens are hover-able devices with mouse pointer... */ }
-3

I know this is an old thread but I thought this might help someone:

Mobile devices have greater height than width, in contrary, computers have greater width than height. For example:

@media all and (max-width: 320px) and (min-height: 320px)

so that would have to be done for every width i guess.

m33x
  • 19
  • 2
-8

Simple! Throw this at the like, bottom of your CSS file and this part of the CSS will be modified within a phone: -

/* ON A PHONE */
@media only screen and (max-width: 600px) { /* CSS HERE ONLY ON PHONE */ }

And voila!

Broteen Das
  • 386
  • 4
  • 12
  • Modern mobile phones can have resolutions eg. 1440 x 3200 (Galaxy S20), 1284 x 2778 (iPhone 12), etc. But due to the portrait orientation and small physical size, you'll likely want to have a mobile-friendly layout instead of a regular desktop layout. – Juha Untinen May 02 '21 at 09:45
  • @JuhaUntinen Modern mobile phones can have resolutions eg. 1440 x 3200 -- only the **physical pixels**. In terms of logical pixels, which are used in css media queries, usual phones lie around `400px X 750px`. The downvotes here seem to indicate that the question wants to detect if UA is mobile browser or desktop browser -- this is needed sometimes to fix the url bar causing viewport height changes. – user31782 Sep 24 '21 at 16:21