Mobile-Friendly: The Mobile Web Optimization Guide

Updated April 2012 to modernise references, eg "will be supported in IE9" and to change the default assumed width in Opera Mobile from 850 to 980 pixels.

Contents

  • Introduction
  • The difficulties of cross-device design
  • You must remember this…
  • Strategy #1: Code well and do nothing special for mobile users
  • Strategy #2: Make a separate mobile site
  • Strategy #3: Build mobile-aware adaptive sites
  • Other useful mobile-friendly techniques
  • Testing, testing, one two three…
  • Summary
  • Resources
  • Introduction

    If I had a Euro for everyone who asks me at conferences how they can mobilise their web site, I'd be extraordinarily rich as well as breathtakingly handsome.

    It's easy to see why people wish to make their sites mobile friendly; Gartner research suggests that by 2013, mobile phones will overtake PCs as the most common Web access device worldwide. And don't forget other visits from devices such as games consoles like Nintendo Wii, DSi, web-enabled TVs, in-car browsers and the like.

    Many customers are already using mobile devices as their main method of Web access, particularly in emerging markets — the July 2009 Statistical Report on Internet Development in China states that the proportion of [people] accessing the Internet by mobile increased enormously from 39.5% in late 2008 to 46% in June 2009, while the proportion of using desktops and laptops decreased. That translates to 150 million people. In the developed world, many have a mobile device as their secondary method of accessing the Web while they're out and about.

    It's a truism that on the Web, there is always someone offering the same service as you are. And if you're not catering for the mobile user, you can be sure that your competitors are. In the current harsh economic climate, sending customers into the arms of the competition doesn't succeed as a business strategy.

    This article provides an overview of three different strategies to make your websites work across all devices. We'll call them mobile-aware websites, as they're not specifically for mobile sites, but they will work on mobile, as well as across different alternative browsing devices. These strategies are not mutually exclusive; you can mix and match as your project, budget and sanity allows.

    The difficulties of cross-device design

    Why is it so difficult to find reliable information on how to code mobile-aware sites? After all, those of us who are adept at using web standards have a corpus of best practices that dates back years. The answer is that the market is still fragmented, although we're seeing more convergence as devices become more powerful (customers are also becoming more demanding, as a consequence.)

    Mobile devices have a wide variety of screen sizes and input methods that range from QWERTY keyboards to touch screens to traditional numeric keypads. Battery life is a problem too; no matter how killer your new web application is, if it eats your visitors' batteries, it's unlikely to be a success on devices.

    Then there is the simple fact that we have a huge variety of devices, and browsers running on those devices. Smartphones can run full Web browsers such as Opera Mobile or Safari/iPhone, while in the developing world we see much lower-end handsets that don't have an operating system but, if they can run Java they can use Opera Mini (a thin client for a proxy-based system that compresses pages down to about 10% of their original size before being sent to the handset for rendering). Opera's monthly State of the Mobile Web report gives useful breakdowns of the different handsets in use across the world.

    You must remember this…

    The mantra for cross-device development is: one site for all is the ideal but it's not always possible. Whichever strategy you adopt, there is one vital point to remember:

    Mobile users are task-focused users. And so are all users

    Many developers and usability pundits advocate making mobile-only sites because mobile users are in a hurry; they're on the go and want to perform one specific task and then finish. A common example cited is that of a restaurant site. The mobile user wants to find the location, the menu and the opening hours so, the argument goes, the mobile site should contain this and nothing else.

    This is a good argument, but it's only half true. If it were 100% true, what would be on the full website? Presumably, a movie of the decor, some atmospheric music, animated representations of the house special dishes, and a downloadable menu in some fancy font. The fallacy here is that users of desktop computers are not task-focussed and have time to waste on an immersive branding experience. The truth is that all users are in a hurry, and all users want to find the information, then leave your site and go and do something more interesting — like taking their partner out to dinner. You should therefore make an effort to reduce clutter and save time for all users — one site should be able to serve the needs of both mobile and desktop users.

    Mantra #2: just because a desktop site allows you more space to fill, it doesn't mean that you should.

    Strategy #1: Code well and do nothing special for mobile

    The current crop of advanced mobile browsers are very good at rearranging content without being told how to by a developer. At the user's request they pan and zoom, reformat a page into a single-column view, remove images, and more.

    Making a good semi-liquid layout that has a min-width and max-width set in your CSS and em-based typography will work very well across a range of different devices and screen sizes. This is also more likely to please your marketing and branding people than a stripped-down mobile-only experience, as well as being more familiar to users who are used to the full desktop site.

    You can deal with people turning off images to speed up the site (and to save money if they're paying by the megabyte, which is still very common on mobile, and in the developing world) by ensuring that you code for accessibility. Using correct alternative text on images not only helps those who can't see images because of a disability, but also those who choose not to download them. There are other parallels between mobile browsing and accessibility: older devices may have no colours or special fonts, so the accessibility requirement not to rely on colour or visuals alone to convey information is appropriate here too. Ensuring good contrast between foreground and background is important; have you ever had to move into the shade to read your phone because the sunlight meant you couldn't distinguish the text properly?

    The catchily-named Relationship between Mobile Web Best Practices (MWBP) and Web Content Accessibility Guidelines (WCAG) provides a useful cross-reference between mobile best practices and accessibility guidelines.

    Other best practices from desktop development have beneficial side-effects for cross-browser development. CSS sprites, for example, were developed to stop the need for JavaScript preloading of background images, itself a workaround to prevent flicker while images load. In the mobile world, every request across the network takes an unpredictably long time, so CSS sprites allow us to reduce the number of HTTP requests and therefore make interaction feel faster and more responsive.

    If you're feeling adventurous, you can add some spice from the fully mobile-aware site methodology. For example, if you have background images on some element, you might use the background-size property so that the background image shrinks or expands to fill its container.

    Strategy #2: Make a separate mobile site

    For some CMS-driven sites this may be the quickest option, but it isn't always the best option longer term: it results in having two sites to user-test, maintain, etc. Of course, in the real commercial world, quicker and easier may often be synonymous with best, so let's see how these work.

    A mobile site usually takes the form of m.example.com, and generally has the same site structure as the full-fat site. This is easily achieved with a half-decent CMS.

    You then need to implement server-side sniffing to divert non-desktop browsers to your mobile site. To do this, you first need to maintain a list of UA strings that browsers send to the server with each request (see Help>About in Opera to see your UA string) — this is how browsers identify themselves to the servers they make requests to. You then test the UA strings from browsers requesting your site to see if they match an entry on the list of UA strings mentioned above and identify as a mobile browser. If so, you send them to the mobile version of the site.

    Of course, if a new browser comes on to the market, the list must be updated or it will return false results, resulting in annoyed users being directed to the wrong site.

    We can't recommend any specific browser-sniffing code because what works today can easily go out-of-date if not actively maintained. As an example, the User Agent (UA) string for the Opera 10+ family of browsers says Opera/9.80. This is because the beta version said Opera/10, but this revealed a problem — sites with browser-sniffing blocked access, mistakenly believing it to be Opera 1 because the authors hadn't allowed for double digits. So beware: if you use browser sniffing, be prepared for continually rewriting and redeploying those scripts on every website for life.

    For reference, the UA string fragment Mobi is a useful identifier for Opera Mobile; the string fragment Mini is a useful identifier for Opera Mini.

    Opera can also be identified by using JavaScript to test for the presence of the window.opera object, although this will disappear in Opera 14.

    A more sophisticated method of browser sniffing is the Wireless Universal Resource File (WURFL); this is an XML configuration file which contains information about capabilities and features of many mobile devices. This allows you to test features, but requires each and every handset on the planet to be in the database with its features correctly identified. And, of course, it needs to be kept up-to-date.

    Because browser sniffing is, by definition, never future-proof, it's absolutely vital that you have a link on every page that sends the user to the full website and remembers the choice in a cookie. That way, if your server-side script doesn't recognise Whizzo-browser as a desktop browser (because the script was written before Whizzo-browser was invented), it will send the user to a mobile page, but Whizzo-browser users can simply click the link to view standard site and henceforth, always get the standard site.

    Designing a template

    You'll need to design a cut-down template, with simple branding and layout etc. for your CMS to squirt content into. Ensure that you have the same structure as your non-"mobile" site, so that if someone follows a deep link into your site, they actually get the content they wanted. It's good practice to offer users a link to the "desktop" version (and vice-versa). Remember their choice with a cookie or in localstorage, but continue offering the alternative version choice.

    Because you're making all the effort to ensure your site is for mobile devices, you should hint to the browser that you've done lots of thinking already so it doesn't need to do all the clever reformatting that devices can do. One way of doing this is to use the viewport metatag.

    The viewport metatag

    When loading a Web page in a full-powered mobile browser such as Opera Mobile, you start with a zoomed-out overview of the page and can then pan and zoom into specific areas of the page in just a few clicks. While this approach works fine for most websites, it is possible to further enhance the user experience for your visitors by presenting a zoomed-in view of the page by default. This approach works particularly well for Web applications, giving them more of an application-like feel.

    By default Opera Mobile assumes a page to be 980 pixels wide, and the zoomed-out overview rescales these values accordingly to fit on the device screen. With a viewport meta tag in the head section of the page you can override this default width and instead set an arbitrary pixel value such as 320, 480, etc. For cross-device compatibility, we recommend setting the width to the device-width:

    <meta name="viewport" content="width=device-width" />

    This adjusts the page width to fit in the full width of the screen, or put differently, it makes one CSS pixel equal to one device pixel.

    Read more in An introduction to meta viewport and @viewport.

    Strategy #3: Build mobile-aware adaptive sites

    The hardest to pull-off methodology is the one that can bring the best of all worlds to your site visitors. A fully mobile-aware site has adaptive content that reacts to device capabilities, and is therefore future-proof as it tests features rather than sniffing browsers.

    The heart of the technique is CSS Media Queries, which are supported by Opera Desktop, Opera Mini and Opera Mobile, Safari (desktop and iPhone/ iPad), Chrome and Firefox and Internet Explorer 9.

    Media Queries are a CSS3 feature that allow you to specify under what conditions a style sheet or a particular set of CSS rules should be applied. For instance, to limit a set of styles to only apply to a screen which is 480px wide or less, you could use the following Media Query:

    @media screen and (max-width: 480px) {
       background-color: red;
       font-size: 1.5em;
    }

    Obviously, you're unlikely to want to turn all the text red. But you might want to send a wide company logo to a header or footer on desktop-sized screens to use as a background image, but a narrow version to smaller screens:

    @media screen and (min-width: 800px {
       #footer {background-image: url(wide-banner.png);}
    }
    
    @media screen and (max-width: 800px {
       #footer {background-image: url(narrow-banner.png);}
    }

    Another common use is to reformat the layout. Here's a simple Media Queries example to demonstrate. On a widescreen, the page has three columns. If you narrow the screen, you'll see the page change layout to a two-column design (I also change the font to reinforce the fact that different CSS is pulled in). Narrowing the screen further gives you a single-column layout, and at a really thin width, all the content is hidden with {display:none;} and instead, a lovely picture is displayed.

    Several different queries are contained within one stylesheet:

    @media screen and (min-width: 800px) {
       @font-face {
         font-family: "demand";
         src: url("demand.ttf") format("truetype");
       }
       h1 {font-family: demand, cursive}
    }
    
    
    @media screen and (min-width: 480px) and (max-width: 800px) {
       body {font-family:"Comic Sans MS", fantasy, cursive;}
    /* [etc] */
    }
    
    
    @media screen and (min-width: 400px) and (max-width: 480px) {
       body {font-family:"Courier New", Courier, monospace;}
    /* [etc] */
    }
    
    
    @media screen and (max-width: 400px) {
       #main {background-image: url(bruce.png); position: absolute; top: 0; text-indent: -10000em; height: 500px; width: 100%;}
       h1, #sidebar, #footer, #pub {display: none;}
    }

    Note the relationship to the viewport width here: when the page is loaded in a desktop browser, the viewport width is the width of the browser window; when it is loaded in Opera Mobile, the viewport width defaults to 980 pixels unless overridden by the viewport meta tag.

    You can try this out for yourself by loading our Media Queries + viewport example in Opera Desktop and then on Opera Mobile, Opera Mobile emulator on your desktop, or Opera Mini. On desktop, we get a three column layout for browser widths wider than 800 pixels — the page gets a different layout when the browser is resized. In Opera Mobile running on a device with a physical screen that's less than 400 pixels wide (as an example, a Nokia 5800 in portrait mode has a width of 360 pixels), a viewport meta of width=device-width triggers the @media screen and (max-width: 400px) { ... } style rules, and the three column page turns into a single column page.

    There are three important points to understand about Media Queries:

    1. The technique does not test for individual devices or browsers, just capabilities, so is inherently future-proof
    2. There is no redirection to different pages going on; it's one page for all
    3. The Media Query is tested before any assets are downloaded. Therefore, no assets are downloaded if contained in a query is false, saving bandwidth and speeding up the display.

    You can view Andreas Bovens' Mobile web development techniques screencast.

    Using Media Queries to turn off resource-hungry CSS

    You may find that some facets of your CSS renders slowly on a resource-constrained device, or uses lots of CPU and drains the battery. The culprits vary between browsers and devices, but animating CSS transforms and transitions and box-shadow have been reported to be resource-hungry.

    As CSS is purely stylistic, you may decide to turn such effects off.

    Other useful mobile-friendly techniques

    Whichever primary method you choose for your mobile sites, you can use some or all of the following techniques as appropriate to your content and functionality.

    Combine files and reduce requests across the network

    As mentioned before, the slowest part of any mobile device Web use is the network. Every image, CSS file, JavaScript file, CSS background image, etc. is called over the network and each of those HTTP requests takes an unpredictable amount of time. We've mentioned CSS Sprites, but other useful techniques are as follows:

    • Combine as many scripts as you can into one file (e.g. utilities.js)
    • Combine as many stylesheets as you can into one file
    • Minify your .js and .css files
    • Make sure your server uses gzip to compress all files it sends
    • Consider using Data URIs for images and CSS background images. This provides a way to include data inline inside web pages. For example:
      <img src="data:image/png;base64,
         iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
         C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
         AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
         REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
         ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
         vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />

      This inserts a red dot onto the page, but no image is requested from the server because it's encoded in that string of letters and numbers. Ian Hickson has a utility to encode Data URIs (Utility source code). This technique can bloat the file size, but that's often better than having to wait for the network to download the external image file.

      Use Scalable Vector Graphics for images

      SVG is a technology that allows pictures to be described mathematically for the browser to draw via markup. So instead of a bitmapped image of a circle and a rectangle, for example, you describe the shapes:

      <svg version="1.1" xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink">
         <circle cx="100" cy="100" r="30" fill="blue" stroke="red"/>
         <rect x="10" y="10" width="80" height="40" fill="yellow" stroke="black"/>
      </svg>

      The browser then draws it like so:

      blur circle and yellow box

      The major advantage with this is that you can zoom in as a far as you like, and the image will never pixellate, because it's redrawn by the browser every time — so it will look as sharp on a small screen as on a widescreen web-enabled television.

      The size of the SVG file will generally be a fraction of the equivalent bitmapped image. In HTML5, you can just embed your SVG code into your markup, thereby saving an network request to grab that file.

      SVG files also work with CSS/Media Queries — here is a fragment of an SVG file that draws a circle and fills it with different colours according to its width (see SVG/Media Queries coloured circle demo):

      @media screen and (max-width: 350px) {
         #circle {fill:  #879758;}
      }
      @media screen and (max-width: 200px) {
         #circle {fill: #3b9557;}
      }

      This technique can be used to simplify logos at smaller sizes. In the SVG/Media Queries simplified logo demo, the logo on the left uses Media Queries to remove the spiral when the logo is shrunk, and then remove the outer circle completely at very small sizes.

      @media screen and (max-width: 256px) {
         #spiral {display: none;}
      }
      
      @media screen and (max-width: 16px) {
         #circle1, #circle2 {display: none;}
      }

      The logic is contained within the SVG file itself, so once written it can be included anywhere and requires no scripting or changes to the pages CSS. (Read more about this technique.)

      Put script elements as far down as possible in the source

      Browsers pause when downloading script elements contained in HTML files. Therefore, put those script elements as far down the source as possible. The reason for this is a psychological one; if your screen is full of content to read (contained before the script element in the source order) the site will feel faster, as the user can read the content while waiting for any interactivity to download.

      (HTML5 specifies how browsers can download and execute scripts without blocking, using defer and async attributes but support is incomplete and specification might change.)

      State the dimensions of images in the HTML

      Always give the dimensions of any images in your HTML, so the browser will download textual content first and leave the correct space for the images while they download (which will take more time as images are significantly larger files than textual content). When they are downloaded, they will pop into the blank space left for them.

      If you don't define the image size, the browser leaves no space. When the images eventually arrives across the network, the browser must then reflow all the text to make room for them. If a site visitor was reading something only to then have it jumped around and scrolled off the screen to make space for a picture, it would probably frustrate or annoy him or her. Also, each redraw of the screen uses a lot of processor cycles and therefore drains the battery faster.

      This works well in sites that don't have mobile optimisation techniques. If later you decide to use Media Queries to make your site responsive, a common trick is to override the HTML dimension attributes and stop images spilling out of their container by adding img {max-width:100%;} to your stylesheet. This, however, only over-rides the HTML width attribute, and keeps the height attribute and thus changes the image aspect ratio. A more robust technique is

      img {max-width:100%;
      height:auto; /* preserve aspect ratio */
      }

      Familiarise yourself with HTML5

      HTML5 has many aspects that can make developing for devices easier. For example, you can store information inside the browser using local or session storage rather than relying on cookies.

      HTML5 forms provide native in-browser validation of certain generic form types; you can test whether an element is a number in certain range, or conforms to a certain regex, or whether a required field is completed, etc., without using JavaScript. Try this HTML5 forms demo in Opera to see it in action. Additionally, some mobile browsers that have their own built-in keyboards (like WebKit on iPhone) give a customised keyboard depending on whether the form type is set to email, number, telephone, etc.

      Use progressive enhancement

      You're probably using a progressive ehancement methodology in your work anyway. In a mobile context, this might be called "mobile-first".

      Do not assume scripting support or Ajax capabilities. For example, Opera Mini renders pages on the server and sends a snapshot of the page to the device, so the page won't change until the user does something on that and there is no way for scripts to run in the background. The user must do something to make Mini talk to the server in order for JavaScript to be unpaused. As a result, you cannot expect things like JavaScript animations or timed Ajax updates to work in the background as they would on a desktop browser. There's much more information in our article Opera Mini and JavaScript.

      Similarly, you should make no assumptions about animation capabilities (canvas, SVG animations, animated GIFs), fonts, colours and the like. Opera Mini development is docmented in-depth in the companion article Opera Mini: web content authoring guidelines.

      Geolocation

      Geolocation isn't just on mobile phones (it's in the modern desktop browsers, too) but as most high-end phones have a GPS facility and are used when on the move, there is a lot of potential to use the W3C Geolocation API for useful applications.

      But it's important to ensure that Geolocation is added as an enhancement rather than as a prerequisite; a user may choose not to share his location with the site for privacy reasons, or is running low on battery (GPS can drain batteries quickly), or is in an area where mapping is rudimentary so accuracy is low.

      A good example of such progressive enhancement is owlsnearyou.com that lists sightings of the bird in your area. If you visit with a geolocation-enabled browser and confirm you wish to share your location, the API will pre-fill a search box with what it believes your current location is. But if that's not correct (or maybe you're in London now but want to check owl sightings in Scotland), you can simply type a new destination into the search.

      If your browser isn't geo-enabled, or you deny permission, the search form is blank so you can type in a place-name or postcode.

      Testing, testing, one two three…

      To round off this article, I will give you tips for easier testing of websites on Mobile browsers.

      Testing on Opera Mobile and Opera Mini

      Opera Mobile emulator can be installed on your desktop and you can therefore use it to test any files that are on your local machine or network before they go live. It's the full product — the same codebase — so you can be certain it's accurate. Opera Mobile emulator allows you to change the UA string to mimic several different popular browsers.

      If you don't have Opera Mini on your phone (and it's available for over 3000 different handsets, so there should be a version for you!) you can test your site using the web-based Opera Mini Emulator. Note that because of the nature of the product, pages viewed in Opera Mini must go through Opera's servers, so the pages you test must be on the Web somewhere (although you could put them behind a password so that no-one else can see your pre-production pages).

      Testing on other handsets and browsers

      We've teamed up with Perfecto Mobile who have a service that allows you to test on different handsets remotely. Opera users can sign up for seven free hours of testing. Additionally, companies like Apple and BlackBerry offer emulators for testing on their products.

      Debugging devices with Opera Dragonfly

      As with earlier Opera Mobile releases, Opera Dragonfly allows you to debug web pages being displayed on your mobile phone remotely from your desktop. To debug pages in Opera Mobile, open Opera Dragonfly in Opera Desktop (Page/View > Developer Tools > Opera Dragonfly) and follow the instructions in our remote debugging article (with video (YouTube) also available.)

      Summary

      We hope you have found our mobile optimization guide useful. We have covered three different strategies for making your sites work better on mobile, numerous optimization tips and tricks, and debugging and testing advice.

      Resources