How to serve the right content to mobile browsers

By Chris Mills

14th December 2011: This article is obsolete

This article is obsolete/out of date, so should no longer be treated as a current or reliable source of information. Please consult the following for more up-to-date information:

Introduction

The modern web is viewed on many different devices, so it is getting increasingly important for us to think about how to create our web sites so that they will serve the right content to users, no matter what device they are using. We have many technologies at our disposal, including media types, media queries, and browser sniffing, but what's the best way to handle this?

In this article I will explore the different ways in which you can develop a web site to serve appropriate content to the different devices used to browse to your web site, and show how best to use them. I'll talk about:

  • Browser sniffing
  • Creating a separate site for mobile browsers
  • Media types
  • Media queries

Of course, it is argued by some that you should be able to ensure that your site will work well in most reasonably modern browsers (desktop and mobile) bydoing nothing except designing them carefully and making sure you stick to POSH (Plain Old Semantic HTML.) This is true to an extent, but fails to take into account that some sites just aren't simple text-based affairs (for example Ajax sites, or sites that feature a lot of multimedia) that need special treatment to get them to play nicely on mobile phones, or just won't work at all (although Ajax will work if you employ Hijax techniques - see Jeremy Keith's first post on Hijax and Jeremy's Xtech 2006 presentation for more. So if your site doesn't fall into these categories, it is worth just doing some simple testing on all the target mobile browsers to see if it provides a satisfactory user experience. You could save yourself a lot of trouble this way. If this is not satisfactory, then read on!

Browser sniffing

Browser sniffing, as many of you will know, is the art of finding out which browser is trying to access your site, and then serving content to it that you think it will be able to make use of based on your knowledge of that browser's standards support, likely screen resolution etc. This is commonly done by looking at the browser's user agent string.

It was very important back in the days of the great browser wars, when IE and Netscape kept adding browser specific features. If you wanted to use any kind of DHTML for example, you'd have to check for IE or Netscape, and then use a totally different DOM structure, and other proprietary constructs. This basically meant coding 2 totally different sites, which was a nasty experience.

Browser sniffing sounds straightforward in principle, but it does have its issues:

First of all, the information you're going to get back about which browser is visiting your site is not always accurate. Many browsers can "spoof" other browsers, ie send back other browser's user agent strings when they are requested. One of the main reasons it appeared was because of irresponsible developers deciding on which sites they wanted to develop for, and then completely excluding any other browser. How many times have you seen a site that says "I'm sorry, but you need to download browser x to use this site"? How annoyed does it make you?

These days, more responsible web developers are using browser sniffing techniques in more responsible ways, to include people, rather than exclude them, as we'll discuss in the next section.

Another thing to consider in this situation is object detection - rather than using the UA string to determine the browser, you detect for the presence of specific browser objects, to determine if your functionality will work or not. This way if a browser lacks a specific object that you are testing for, it will just bypass that code safely without failing, and then be able to access that code if support is added in future versions, without you needing to make any changes to your script. We will follow up this article with a more detailed look at server-sniffing methods in the next couple of weeks - watch this space.

Creating a separate site for mobile browsers

Back in the days when the mobile web was very young, and the only thing available to phones was WAP/WML sites (yum!) this of course was the only option you had. It was common to see sites like wap.myplace.com alongside www.myplace.com, and if a user navigated to the desktop version by accident, some good old fashioned browser sniffing could be employed to forward them on to the right site.

These days, the same kind of principle is often used to differentiate between desktop and mobile sites, because even though mobile browsing power has increased a great deal, and mobile web pages can now run on the same technologies that desktop pages do, some sites will not run well at all on many mobile browsers, particularly large ones, with lots of multimedia.

With responsible browser sniffing, you can detect what browser a user is using and then serve them an appropriate site that will work on their browser.

But there are still issues here - 2 versions of a site means 2 copies of the same content to maintain, which can be a nightmare, and forcing the user to remember 2 URLs can be painful (unless of course you have 1 central URL, and then do redirects as appropriate.)

If you use browser sniffing/object detection to redirect to a mobile site then you should include a link (preferably at the top) to redirect to the regular desktop version (with a cookie to store the user's choice) in case the user doesn't agree with your optimisations and wants some content that is only available on the regular site, or just prefers it. A mobile users *shouldn't* be excluded from the regular experience.

In many cases it is best to have one version of the site that adapts to the user agent, and this is what we'll look at next. Exceptions to this do exist - the decision depends on the content and audience of the site. For example, a very complex heavy webapp would benefit from a separate mobile site to display just the specific functionality that mobile users could benefit from (some good examples of this can be seen in Brian Suda's article here. Conversely, a site that is designed specifically for the mobile context, for example using location aware services - such as automatic display of specific hotel or weather information for an area - wouldn't make sense on the desktop. It would be better to have a separate desktop version that allows you to just search using keywords (this would also be used by mobile handsets that don't have the ability to give location information.)

One site to rule them all (sorry, couldn't resist it)

To create one site that will adapt to the user agent visiting it, we have a few options.

To deal with dynamic content such as JavaScript menus, it is best to employ graceful degradation techniques to ensure that the site is still usable if the JavaScript functionality fails. In anycase, a sensible design will win out here - a huge DHTML style animation certainly won't work very well on a low power mobile browser with a 240 pixel screen available, so don't serve it to them.

For CSS on mobile devices, the main concerns are altering the layout so that it works on a much smaller screen size, and keeping your background images in check so that you don't wallop your mobile users with huge downloads. The 2 ways of handling this are with media types, and media queries.

Media types

Media types allow you to specify different stylesheets for different media types, for example screen (the default in most browsers,) print (for the printed page,) and most relevant to this article, handheld for handheld devices. You could use the following lines to import an appropriate stylesheet for the desktop browser, or ignore that and import a different stylesheet appropriate for mobile devices if the user agent is a phone:

<link rel="stylesheet" href="screenstyle.css" type="text/css" media="screen, projection" />
<link rel="stylesheet" href="handheldstyle.css" type="text/css" media="handheld" />

Opera Mobile 8.65 and Opera Mini beta 1 and 2 supported handheld by default, whereas future versions of Opera Mobile and Opera Mini 4 use the screen stylesheet by default, and allow users to switch to small screen rendering mode/mobile view to use the handheld stylesheet - this reformats the handheld stylesheet into a single column if it is defined.

Why did Opera do this? Well, the main issue with handheld is that you are not giving the user much of a choice of what content is delivered to their phone. These days, phones are much more powerful than they used to be, and it is a bit insulting to have a web site see you are a mobile device, and then serve you a really dumbed down version of it's content, even thought the device could quite easily support the full desktop version of the site. If you check out Opera Mobile 8.65, or WebKit on the iPhone, you'll see a browser of comparable power to their desktop cousins. For these reasons, Opera decided to favour media queries.

Other browers have varying support - the Nokia S60 browser and iPhone (both WebKit-based) browsers don't have SSR/mobile mode, and just rely on the screen styles - they basically try to be desktop browsers, but on a phone (as does Opera Mobile, with Mini being somewhere in between, depending on the power of your handset.) With Pocket IE , Netfront and Openwave on the other hand, you need to rely on the handheld stylesheet, as they don't support media queries correctly - IE often just ignores entire stylesheets if they contain media queries, whereas the others usually just apply all the styles inside them regardless of the situation (see below for more on media queries, and check out this HowToCreate article for more on mobile browser support for media types/queries.

Media queries

Media queries are part of the CSS3 spec, and quite simply are a way to insert decision statements into your CSS, similar to if ... then ... else constructs in traditional programming. The idea is that you can check for a condition in the user agent (such as browser window width) and choose to ignore the styles within that block if the condition isn't met. For example (in the real world, this style blocs would be in a separate stylesheet, and then imported into the web page using a link element - this is just for illustrative purposes):

<style type="text/css" media="screen,projection">
  
 /* Insert your rules for desktop and other big browser windows here */

  @media only all and (max-width: 480px) {
    /* Insert your rules for smaller screens here */
  }

</style>

This will apply the rules contained within it on any browser where the screen width is smaller than 481px wide - this happens dynamically as you resize the browser window, and these rules override anything set outside the media query. Again, this is the theory - there are issues with browser support here. IE and Safari versions 1 and 2 (and other earlier WebKit-based browsers) don't understand the media query. The rather bizarre only keyword is needed, otherwise Firefox 2 and 3 doesn't understand it either (these, and other Gecko-based browsers will use all the media query statements even if the media query returns false - they understand all, but don't understand the media query, so they return false, but instead of ignoring it they render the content. Unless only is used in addition to all.) Safari 3 (and iPhone and iPod touch - WebKit) and Opera 7+ (including Opera Mobile 7+ and Mini 4) are the only browsers that interpret media queries totally correctly at the time of writing of this article. See this article on safe media queries for a much deeper discussion on how use media queries across different browsers.

One of the best ways to tackle this is by using a combination of the 2 above methods, as follows:

A combination works best

We recommend that you employ the following approach:

<style type="text/css" media="screen,projection">
  
 /* Insert your rules for desktop and other big browser windows here */

  @media only all and (max-width: 480px) {
    /* Insert your rules for smaller screens here */
  }

</style>

<style type="text/css" media="handheld">
/* specific mobile design rules for handheld devices with small screens, which don't support media queries. */
</style>

With this approach we leave the decision to the user. They can decide how they want to view the site, as long as the site or the browser they are using gives the the choice (Opera Mini for example.). A lot of users of course will just go for the default because they don't really understand the options being presented to them, but at least the media query is there to help optimize the site for them. The handheld stylesheet is still there as well, for browsers that don't understand media queries (like Pocket IE, Netfront, early versions of Opera Mini and Openwave.)

There is still a slight issue with this approach - browsers using the regular screen stylesheet will have to download a larger stylesheet, due to all the additional rules inside the media query, and furthermore, *all* the styles are acted upon in this case, not just the ones inside the media query - the rules inside the media query override the rules outside it, giving you the desired layout on your small screen browser. Of course, you can minimize how much of an issue this is by using media queries responsibly. You don't need to repeat the entire stylesheet inside the media query - just override the rules that need it.

Summary

I hope this article has been useful to you in deciding how to tackle the issue of serving your content to different devices. The road ahead isn't easy by any means, but as specs and spec support improves, and mobile devices get more powerful, some of the issues discussed here should subside somewhat.

Chris Mills is a web technologist, open standards evangelist and education agitator, currently working at Opera Software in the developer relations team. He spends most of his time writing articles about web standards for dev.opera.com and other publications (such as .net mag and A List Apart), giving talks at universities and industry conferences, and lobbying universities to improve their web education courses. He believes that education is the answer to everything, but in particular he is passionate about using education to improve the overall content quality, accessibility, usability and future-viability of the Web.

He is the creator of the Opera Web standards curriculum, contributor to the WaSP InterACT project, and coauthor of InterACT with web standards: A Holistic Approach to Web Design. In August 2011, he also accepted the position of co-chair of the newly-formed Web Education Community Group.

Outside work he is a heavy metal drummer, proud father of three and lover of good beer.


This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license.

Comments

The forum archive of this article is still available on My Opera.

  • photo

    stlouisweb

    Tuesday, December 20, 2011

    Cool article, but what if I wanted to do this in reverse. That is we have a site that displays different styles based on the device. And, what I would like to do is implement the site in an iframe on a certain social networking site, so that it displays the mobile version when viewed through the iframe regardless of the device on which it is being displayed?
  • photo

    Chris Mills

    Monday, January 9, 2012

    @stlouisweb this is an interesting idea. So what you are saying is that you have a responsive/adaptive site, and you want to not only display different styling on desktop/mobile/tablet, or wide screen/narrow screen/small screen device (depending on how you want to look at it), but you also want to display the mobile version of the site inside an iframe, kind of like a component or widget inside certain sites?

    How are you doing then responsive/adaptive design? Media queries? Give me a few answers to these questions and then I'll chime in. I might have a few ideas for you.

    Best regards.
No new comments accepted.