8 Techniques for Mobile & Retina Devices Detection

by Rochester Oliveira

on July 2, 2013

in Resources

Despite of the awesome mobile browsers we have available nowadays, sometimes the best thing to do is to serve content at least mobile-optimized. But in order to do this you need to first detect which visitors are coming from mobile devices and which aren’t.

Today we’ll see a few ways to detect mobile browsers so you can chose the best suitable to your needs, and give your user the best experience possible.

#1 PHP User Agent

When the browser requests your server the page, it also sends some data about itself, like post data, referrer and the user agent. We could test the user agent comparing with a list of known mobile user agents so you can redirect the user to a different version, add a new cookie, set a global variable to be used in your CMS, set a HTML class or anything else you may want to do.

The code itself is quite simple, and we can make use of the preg_match() function to compare current browser with an array of mobile browsers:

<?php
    //Here is the known mobile user agents list
    $mobiles = array("iPhone","iPod");

    foreach( $mobiles as $mobile ) {
        if( preg_match( "#".$mobile."#i", $_SERVER['HTTP_USER_AGENT'] ) ) {
            //Ok, this is a mobile browser, let's redirect it!
            header('Location:http://mobile.mysite.com/'); 
            exit();
        }
    }
?>

This code is quite handy because you can disable this test, via Cookie for instance so users that want to actually see your desktop version can do that using a link in your footer. The trick is, you set a link to yoursite?nomobile=1 then you can test this var before doing the redirection part:

<?php
    //let's check if we have a get or post or cookie set to nomobile
    if ( isset( $_REQUEST['nomobile'] ) && true == $_REQUEST['nomobile'] ) {
        //now we check if we have set the cookie, so we don't need the "get" in the URL all the time
        if ( ! isset($_COOKIE['nomobile']) ) {
            setcookie("nomobile", 1, (time()+60*60*24*30) );
        }
    } else {
        //nevermind, let's check if current browser is a mobile

        //Here is the known mobile user agents list
        $mobiles = array("iPhone","iPod");

        foreach( $mobiles as $mobile ) {
            if( preg_match( "#".$mobile."#i", $_SERVER['HTTP_USER_AGENT'] ) ) {
                //Ok, this is a mobile browser, let's redirect it!
                header('Location:http://mobile.mysite.com/'); 
                exit();
            }
        }
    }
?>

#2 JavaScript User Agent

This could be done also using JavaScript. The code itself is surprisingly similar to the PHP counterpart, but the use case differences are huge.

While PHP is more global the JS alternative seems to be more suitable for places where you have little or no control on the server side code, or you want to do something specific (like a landing page).

Overall the JS code is limited because you need to actually load the entire site before doing the redirection, which is the exact opposite of the PHP alternative which requires you to add it as the first thing in your page (otherwise the location code won’t work).

So, here is an example:

<script type="text/javascript">
    var mobiles = array["iPhone", "iPod"];//mobile devices
    var i;

    for(i=0;i< mobiles.lenght;i++){
        //testing if the RE matches the mobile agents
        var er = new RegExp(mobiles,"i");
        if( er.test( navigation.userAgent ) ) {
            window.location = "http://mobile.mysite.com/" ;
        }
    }
</script>

#3 WordPress code

WordPress actually has an internal mobile sniffing tool so you’ll have a global variable to tell you if the current user is an iPhone or not (and a few other browsers). Based on this you could enqueue specific scripts and styles, or load / erase specific parts of the code.

Here is an example:

<?php
    function load_my_styles() {
        global $is_iphone; //loading global var here
        if( $is_iphone ) {
            wp_enqueue_style( 'iphone-style', get_stylesheet_directory_uri() . '/ iphone-style.css');
        } else {
            wp_enqueue_style('normal-style', get_stylesheet_directory_uri() . '/ style.css');
        }
    }
    add_action( "wp_enqueue_scripts", "load_my_styles" );
?>

#4 WordPress Plugins

As Apple’s motto is “there’s an app for that”, WordPress’ motto should be “there’s a plugin for that”. It’s impressive the amount of plugins (good and bad ones) making pretty much anything you imagine possible without ever having to touch code lines.

So, you can find a few plugins to help you on this, a few require some code, a few don’t. Here are a couple of options:

 

php-browser

mobile-detector

#5 HTML Code for Retina

Back in the year of 2010 we first saw the “retina screen” term in use, and it was kind of awesome. But it meant also a huge change, since all images and code in your site could look blurry if you weren’t ready for it.

There are plenty of ways to detect mobile browsers, as we’ve seen before, but there are even easier ways to detect retina devices, if you are looking for an easy way to replace your images for hi-quality images.

This is a simple way to be done in your <head>, while you’re calling your styles:

<link rel="stylesheet" type="text/css" src="css/common_style.css" />
<link rel="stylesheet" type="text/css" src="css/retina.css" media="only screen and (-webkit-min-device-pixel-ratio:2)" />

But then we’ve found a better way to do this, let’s check it.

#6 Media queries

The media queries allow you to conditionally apply styles if a certain rule returns the TRUE value. In order to get this working we have a few possible variables like browser width, device width, and pixel density. Here are the common media queries as we can find in the 320 and up boilerplate:

/* Smartphones (portrait and landscape) ----------- */
@media only screen 
and (min-device-width : 320px) 
and (max-device-width : 480px) {
/* Styles */
}

/* Smartphones (landscape) ----------- */
@media only screen 
and (min-width : 321px) {
/* Styles */
}

/* Smartphones (portrait) ----------- */
@media only screen 
and (max-width : 320px) {
/* Styles */
}

/* iPads (portrait and landscape) ----------- */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) {
/* Styles */
}

/* iPads (landscape) ----------- */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : landscape) {
/* Styles */
}

/* iPads (portrait) ----------- */
@media only screen 
and (min-device-width : 768px) 
and (max-device-width : 1024px) 
and (orientation : portrait) {
/* Styles */
}

/* Desktops and laptops ----------- */
@media only screen 
and (min-width : 1224px) {
/* Styles */
}

/* Large screens ----------- */
@media only screen 
and (min-width : 1824px) {
/* Styles */
}

/* iPhone 4 ----------- */
@media
only screen and (-webkit-min-device-pixel-ratio : 1.5),
only screen and (min-device-pixel-ratio : 1.5) {
/* Styles */
}

But this is an interesting one, if you want to target only retina devices (to change a background image or your logo, for instance):

@media only screen and (-webkit-min-device-pixel-ratio:2){
}

#7 Media Queries via JavaScript

This is one of the most obscure techniques I’ve seen (the craziest is the next one, but wait for it). You could test media queries using JavaScript, and if returns true, for example, you could conditionally change classes, change image src attributes, redirect your page.

In my humble opinion this method is even better than the pure JS method, because it allows you to improve the user experience when similar alternatives are rare. What I mean by rare alternatives? For example, to do something like this using PHP code it would require a PHP parser, to search every image tag in your page and replace their SCR with the retina URL. With JavaScript and jQuery this is a piece of cake.

<script type="text/javascript">
    //JS version for the retina query
    var modern_media_query = window.matchMedia( "screen and (-webkit-min-device-pixel-ratio:2)");

    if( modern_media_query.matches ){
        //DO ALL THE THINGS HERE
    }
</script>

#8 Htaccess code

So, here we are with the darkest black magic available to do this. The idea is the same behind the first PHP method, but the final code is quite different.

RewriteCond %{HTTP_USER_AGENT} “ipod|iphone|ipad|blackberry”[NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^ http://m.yoursite.com%{REQUEST_URI} [R,L]

The first line checks the user agent, and if it matches our search it’ll “save” it. Then the second line will get the current page, and the third line will redirect you to your mobile URL.

What do you think?

So, which of these methods do you like the most? Which have you implemented? Are you planning on implementing any of these? Let us know using the comments section!

Powered by Shutterstock

About Rochester Oliveira

Roch is a web designer and entrepreneur from Itajubá (MG), Brasil. He loves writing about obscure topics and doing some cool stuff. Connect with Roch on Google +