~/blog/mobile-detect|
Scan this vCard to save my contacts
#frontend

How to detect mobile devices on Web?

August 27, 2022 · 5 min read

Table of Contents

What is this about

In Frontend, it's required sometimes to handle mobile users differently. For example, if an app or website has a separate version for mobile devices.

Below you can find several techniques I've found during my last investigation in this area. All the approaches are sorted from the most adequate to the most controversial and even absurd.

Test UserAgent

The oldest and probably the most popular approach is to make a check against the User Agent string.

function isMobile(userAgent: string) {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(userAgent);
}

Pros:

  • Works on the server
  • Quite easy and covers all the devices

Cons:

  • Regular Expressions
  • Easy to cheat by overriding User Agent

xkcd perl problems

Source: xkcd Perl Problems comics

This is the only way we can follow while working with SSR or SSG frameworks. All the techniques described below, unfortunately, are for SPAs only.

Use navigator.userAgentData

Relatively new API that I have high hopes for.

function isMobile() {
  // @ts-expect-error Experimental property
  return navigator.userAgentData.mobile;
}

Pros:

  • Promises to be more accurate
  • No need to parse UA strings

Cons:

  • Works only on the client side
  • Is not yet widely supported

Check screen orientation property

Not the most accurate way to make a guess, because nowadays, there are a lot of tablets and transformers on the market.

The idea is to check whether screen.orientation is supported or not.

if (typeof screen.orientation !== 'undefined') {
  // We can make a guess that our user is a mobile owner
  // ... or tablet
  // ... or Microsoft Surface
}

Unfortunately, Safari doesn't support it either on Desktop or on iOS.

Cons:

  • Sounds like a shot in the dark
  • Lack of support on iOS

Check touch screen support #1

I didn't find any better description of this CSS feature rather than citing the MDN docs:

The pointer CSS media feature tests whether the user has a pointing device (such as a mouse), and if so, how accurate the primary pointing device is.

MDN docs

Considering this, we can assume that if the pointing device is not very accurate, it should a touch screen. Initially, this feature should be used to, for instance, make some UI elements bigger for touch screen users and smaller if they have a mouse connected.

function isMobile() {
  return matchMedia('(pointer:coarse)').matches;
}

Check touch screen support #2

Let's consider another way to check if a user visits our app using a touch screen device, that potentially may be mobile.

function hasTouchScreen() {
  return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
}

ontouchstart allows us to assign event listeners that will be run when a user taps or performs a gesture, while maxTouchPoints contains a maximum number of touch points supported by the device.

  • No way to distinguish mobile, tablets, and laptops with touch screen

Check screen size

This might be the least reliable thing we could do, but if the logic is highly tied to the size of the screen, it might work as well.

I wouldn't recommend it as a standalone check, only together with other methods, described above.

function isMobileViewport() {
  return matchMedia('only screen and (max-width: 767px)').matches;
}

Conclusion

Everything described above can be combined to maximize detection precision, but it still is a dirty solution.

Consider persisting the check by saving it into sessionStorage or localStorage to avoid unexpected behaviors while connecting external pointer devices, rotating the phone, or forcing desktop view mode.

In 2022 there are still no reliable methods to apply for detecting mobile devices, but perhaps this is for the best.

Remember, that the Web was designed to be equally accessible by everyone.

See also: