Mobile phone detection

From Exterior Memory
Jump to: navigation, search

Mobiles phones typically have limited screen space, and desire a different layout than one would expect in a regular browser. It is often not possible to make a style sheet that looks good on both devices.

Use CSS Media Selector

Ideally, you should let the browser decide how to best render the page, and only give hints to the browser for the best style to pick. The CSS media selectors are specifically designed for this goal:

<link rel="stylesheet" href="main.css" type="text/css" />
<link rel="stylesheet" media="screen,projection,tv" href="screen.css" type="text/css" />
<link rel="stylesheet" media="print" href="print.css" type="text/css" />
<link rel="stylesheet" media="handheld" href="mobile.css" type="text/css" />

Unfortunately, the handheld media type is hardly supported in practice, so the above does not work well in practise: nearly all mobile browsers follow the screen media type (the print media type is correctly supported and can be used to change the style sheet when the document is to be printed).

Use CSS Media Queries

CSS3 has advanced media queries which enhance the media selection mechanism with additional logic, like window width (min-width and max-width), monitor width (min-device-width, max-device-width), orientation (orientation:portrait, orientation:landscape), etc.

.box3 { background: red; }
@media (max-device-width: 699px) {
   .box3 { background: green;
}
@media (min-device-width: 700px) {
   .box3 { background: yellow;
}

This works well in most browsers, and is a very effective way to specify an alternate style sheet for mobile devices. The media query can also be used in the HTML page itself:

<link rel="stylesheet" media="all and (max-device-width: 699px)" rel="stylesheet" href="mobile.css">

In the above examples, the device-width is used to distinguish between small and a large screen size. width can be used to detect a small window size (as opposed to screen size). On the iPhone and iPad, the width is considerable larger than the device-width, since the Mobile browsers renders the page at full resolution and than scales it down or let the user pan over the page, so it is best to use device-width.

Use Javascript

It is possible to use Javascript to select the style sheet to use. The proper constant to query is window.innerWidth. Unfortunately, this is not supported by Internet Explorer. Internet Explorer does support the document.body.clientWidth and document.documentElement.clientWidth constants, but the meaning depends on the version and mode of IE (window width or document width), not to mention that the document.body constant can only be queried in IE after the page is rendered, defeating the purpose.

You can either choose to ignore the buggy Internet Explorer (serving the default stylesheet), or instead query the screen.width, which gives the size of the monitor, instead of the window.innerWidth.

<script language="JavaScript" type="application/javascript">
var newcss = document.createElement('link');
newcss.rel = 'stylesheet';
newcss.type = 'text/css';
if (screen.width >= 800) {
  newcss.href = "screen.css";
} else {
  newcss.href = "mobile.css";
}
document.getElementsByTagName('head')[0].appendChild(newcss);
</script>

This gives correct results in all browsers I've tested, even though there are a few quirks in the screen.width value (in Safari, the result on a 1440 pixel wide monitor was "1296", and -to my surprise- correct on a computer with two monitors, where the result depended on which screen the window was located upon loading the page).

Use User Agent detection

By examining the User Agent string that browsers send in their requests, it is possible to determine if the request was sent from a mobile device or not.

Simone Cingano compiled an extensive list of known user agents, which could be used for this purpose:

  • The presence of the word "MIDP" (Mobile Information Device Profile), as in "Profile/MIDP-2.0" or "J2ME/MIDP" identifies nearly all regular phones (non-smart phones).
  • The presence of the word "Mobile" identifies Webkit-based browsers on iPhone, iPod touch, iPad and Android; as well as Internet-Explorer on Windows Mobile.
  • The presence of the word "IEMobile" identifies Internet Explorer on Windows CE.
  • The presence of the word "Fennec" identifies Firefox Mobile.
  • The presence of the words "Opera Mobi" or "Opera Mini" identifies Opera based browsers on mobile devices (although most were already detected with the word "Mobile" for Opera Mobile or "MIDP" for Opera Mini)

Observe that I have chosen to detect browsers instead of devices (such as "iPhone" or "Android"), since it appeared that would yield many more options. Apple alone already uses 3 strings ("iPhone", "iPod" and "iPad"), not to mention Nokia, Samsung, BlackBerry, etc. etc. Relying on this would be a nightmare to maintain.

The only device which is not reliably detected is the Palm, since those user agents strings varied too much.

<?php
if (preg_match('/\b(\/MIDP|Mobile|IEMobile|Fennec|Opera Mini|Opera Mobi)\b/i', $_SERVER['HTTP_USER_AGENT'])) {
  $stylesheet = 'mobile.css';    # Mobile device detected
} else {
  $stylesheet = 'screen.css';    # Regular browser or crawler detected
}
?>

Crawlers and Screen Readers

Crawlers (like Googlebot, Bingbot and Yahoobot) and screen readers (for visually impaired readers) should just be served the regular style sheet, since they typically ignore the style sheet anyway.

The User Agent can be used to detected crawlers, but not to detect screen readers, since screen readers typically sit on top of web browsers and do not alter the User Agent string.

There is a media selector for screen readers, but I don't know if that is supported:

<link rel="stylesheet" media="speech,braille" href="screenreader.css" type="text/css" />

Further Reading