Delivering a responsive layout

patterns & practices Developer Center

On this page: Download:
Why use responsive design? | Targeting features and capabilities | Managing expectations | Evolving your design process | Defining breakpoints and structuring style sheets - Choosing the number of style sheets | Delivering responsive images - Creating flexible inline images, Resizing background images, Image replacement techniques | Summary Download code samples

Why use responsive design?

Responsive design is a technique that enables developers to adapt the layout and design of an app to suit multiple screen sizes. This is implemented using a series of CSS media queries that trigger layout and stylistic changes. These changes occur once a device property (such as screen width) meets the criteria defined within the media query. Developing a site in this way provides several advantages.

Developers can design and maintain one set of markup (with the occasional minor variation), and in doing so, support a wide range of devices. This reduces the number of templates and resources that must be designed, and avoids duplication of any future design, implementation, or maintenance efforts. The app is also easier to promote, as there is only one domain, and one URL for each article, section, or feature on the website. This is particularly helpful in today’s highly connected world as URLs shared by email or using social media will resolve gracefully regardless of the device.

The technologies required to design responsively are also widely supported, and by creating the markup and styles "mobile first," it’s possible to design around devices without the necessary media query support.

Responsive design is most often applied to a single site (or app), enabling it to adapt to all contexts—from small portable devices, all the way up to desktop computers (and even larger screens such as televisions). There is, however, no reason it cannot be used to improve apps that have been explicitly designed to suit a mobile context such as Mileage Stats.

Note

See Choosing the number of style sheets for more information about the "mobile first" technique.

Targeting features and capabilities

Responsive design is ideal for mobile, as it enables developers to target a wide variety of screen sizes. It enables you to detect devices that share a common screen size, and deliver specific CSS to those devices. Where it falls short, however, is in addressing the variety in browser implementations.

A group of devices may all share a screen width of 320 pixels, but one of these may be a lower-powered smartphone with a basic browser and QWERTY keyboard, while the other may be a high-capability, touch-enabled device with a next-generation rendering engine. The last thing you may want is to serve the same CSS, JavaScript (and sometimes even HTML) to these two devices.

For these reasons, we decided to implement several additional levels of feature detection for Mileage Stats Mobile. These additional steps would enable us to detect not only the screen size, but additional capabilities such as support for JSON, XHR, Canvas, and the HTML5 geolocation API.

See Detecting devices and their features for additional information.

Managing expectations

A critical step in responsive design is managing expectations. Stakeholders must understand, and buy into, concepts of progressive enhancement, graceful degradation, and the need to design in accordance with device capabilities and constraints.

They must understand that there will be no single, pixel-perfect reference version of the design. Each device (and browser) will render the design to the best of its capabilities. Font size and line length will vary (within an appropriate range). Design elements (such as gradients and rounded corners) may appear on one device, but not another, and the brand colors may shift based on a device's screen quality, brightness, contrast settings, and environmental factors such as lighting.

This is perfectly normal, but it’s important to prepare all manner of stakeholders for this reality. This is particularly important for the test team, who will encounter the app on many devices and should be able to distinguish between actual bugs and design differences caused by varying levels of HTML or CSS support.

Evolving your design process

Another key factor in developing a responsive experience is a willingness to vary your design process. Your app will not only be flexible, it will adapt its appearance and UI, its layout, and even certain features to suit the capabilities of each device. To deliver the best product, your design process will need to be as flexible as the app you are creating.

Responsive design is a fairly new practice, so best practices are still emerging. What is becoming clear, however, is that it’s counterproductive to approach the design of a responsive app using only static and pixel-perfect mockups or wireframes.

While we cannot offer a formal set of recommendations, the list below outlines suggestions based on the process we used when developing Mileage Stats Mobile:

  • We started working in HTML quite early, creating exploratory prototypes based on the data and app flows of the original Mileage Stats app. These prototypes were extremely simple, with very little visual design, but helped kick off and inform the overall design process. They also helped us uncover problem areas caused by lack of space, and the need for a clearer way of finding mechanisms on smaller screens.
  • As the app was based on an existing product, we decided not to spend too much time wireframing the application flow. We focusing instead on uncovering, prototyping, and eventually documenting the differences between the existing desktop app and the new mobile version.
  • We created preliminary visual design mock-ups with variants to represent common mobile phone and tablet screen sizes. These helped the team visualize the product while keeping in mind that actual screen sizes would vary. We also began work on the actual templates (based on these designs) quite early, testing all design iterations on target devices to ensure feasibility and uncover problems as soon as possible.
  • Our final design documentation consisted of fewer than 30 pages. Rather than document every flow and every detail of the UI, we provided just enough information to ensure that design, development, and testing would all essentially be playing from the same page moving forward. This document—combined with prototypes and small functional tests—created a living spec and provided far more accurate context than a larger document would.

Defining breakpoints and structuring style sheets

A common question when designing a responsive app is how to structure your breakpoints. Breakpoints are the thresholds or criteria at which a media query will execute. These will typically correspond to a screen size, but the question is: how do you decide which screen sizes to use?

A primary reason to create a responsive design is to ensure that the app looks good at different screen sizes. Although it may appear counterintuitive, it’s best to ignore screen size at first, and instead consider your content and layout.

During the design of Mileage Stats, we frequently tested the layout on a desktop browser (by resizing the screen to simulate different sizes). In doing so, we determined that the main view didn't feel quite right when stretched wider than 640 pixels. We therefore chose to introduce the breakpoint for an additional split-pane layout at that width. This layout change was implemented with the addition of the extended.css style sheet.

This design decision was cross-checked on a variety of wide-screen mobile devices to ensure that the breakpoint was appropriate and all aspects of the layout felt balanced.

JJ149683.307F4AA48D4FBDCDD35297ABD366F793(en-us,PandP.10).png

Example A shows the Mileage Stats Mobile layout up to the 640-pixel breakpoint. Example B shows the addition of the second pane.

Choosing the number of style sheets

Given that each HTTP request causes latency, you might expect that combining all your style sheets would be a good idea. There is, however, some benefit to loading several distinct style sheets that progressively enhance the experience based on a variety of criteria.

The first benefit comes from a mobile-first approach to structuring your style sheets. Most smartphones now include a browser that supports CSS media queries, but users may be using an older device, or a low-cost feature phone. A mobile-first approach structures your CSS so that the smallest, and least capable device doesn’t receive the styles destined for more capable devices.

The first step is to create a style sheet with only minimal styling for default HTML elements such as headers, paragraphs and form elements. This style sheet has no media query breakpoint, so it is served to every device (including those that don’t yet support or understand media queries). Structuring style sheets in this way is what we mean by "mobile first" as it doesn’t penalize web browsers with no media query support. These browsers receive a simple, "good enough" experience that prioritizes speed, legibility, and widespread availability.

<link rel="stylesheet" type="text/css" href="../styles/css/default.css" media="screen, handheld" />

Note

Most devices, as well as desktop browsers use the "screen" media type; however, certain older mobile browsers use the "handheld" type. We have specified both to ensure that all browsers download this particular style sheet.

The next step is to create a style sheet with the next layer of styles and layout. For Mileage Stats Mobile, this style sheet was defined using a 320-pixel breakpoint, as this is a common base size for smartphones.

<link rel="stylesheet" type="text/css" href="../styles/css/enhanced.css" media="only screen and (min-width: 320px)" />

This style sheet shouldn’t replicate the styles supplied in the first; it should instead build on them. Let’s say, for example, that we want all h2 elements to be 1.2 em in size, but as screens get larger, we want to surround them with a blue border. We would therefore set all h2s font size to 1.2 em in the default style sheet, but only include the enhancement—in this case, the blue border—in the second style sheet.

We then repeat this approach with the third style sheet, which in this case begins at 640 pixels and primarily focuses on changing the layout to suit wider screens. There is no need to reapply default styles for fonts, lists, and form elements, as these were applied in the first style sheet and will cascade to all the others. What this also means is that the second and third style sheets are often much smaller than the first.

Note

Serving a larger style sheet to a smaller device may seem odd, but remember that these are all default styles that a user would need to download regardless.

By keeping these style sheets separate, the smaller devices won’t (in theory) download or use the CSS meant for larger devices, but there is also a second advantage. These style sheets (and the media queries that control them) have so far been specified in the document head. Now that the style sheets are separate, we can add a second layer of media queries inside the CSS documents themselves.

This second layer is best reserved for small tweaks in layout or content. For example, you may find that when the screen is larger than 500 pixels, copy becomes uncomfortable to read due to the width of a line of text. It isn’t worth creating an entirely new style sheet (and breakpoint in the head of your document) to fix this small problem, but you can add a media query within the second style sheet to enable that adjustment.

An example of this technique can be found in the default.css style sheet. This style sheet is served to all devices, some of which will include a screen that is less than 320 pixels in width. On these smaller screens, there isn’t room for the arrow icon that is displayed next to each fill-up and reminder record. We have therefore omitted this icon in the default design, then use a media query to add the icon on screens that meet the minimum size criteria (which we determined through testing was 320 pixels).

@media (min-width: 320px){
.widget.fillup tr td:last-child,.widget.reminder tr td:last-child {
padding-right:1.75em;
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAQCAYAAAAMJL+VAAABYElEQVQ4ja2Uv0sCYRjHP9oPBRu65VBxSZEQbJCCoKZIB4eGBqGbggaHdlcHV/+DhlYDh8YGjbYi6GjIoYYKXJJbjoZAK7OhO7H3zt4z/C4v7wPf5/M+78v79Q0GA0ZVrtaKQBYo8Ft1oFkpaUdMIJ8NKFdrCtAAViUeHchVSprpGWA1fwQUjwczgYQXiN9aG2LzTDrO4X6eYGDezWdPK9XMV2i5CBRHi6lkjMLOBguhIMmlKHf3bT77fdEbvbhsvWxtruiyCcTH5Llt0O19ABBWFznY2x43icPrBsiKxW7vneOTcy8Qh9cN4KqOYbpCJtVYAEBEVQgG5ob7K/1heoBMOs5ufn24Pz275rb19C9AUyymkjGvzR1eN0BdLJqvb8O7l5zc4RVl/+QbhIgIqwoRVfmruV4paWsywKy15hCiomOYdIyxSWBaHqn8AFamJPgJMpl0POYQjKSprWnH9TfLX4TCilQ89gAAAABJRU5ErkJggg==);
background-repeat:no-repeat;
background-position:center right
}
}

JJ149683.33F3E7070E4351F3E737D8091F562A52(en-us,PandP.10).png

The arrow icons shown surrounded in red are only loaded once the screen width reaches 320 pixels.

Note

The arrow icon has, in this case, been provided as a data URI. See Delivering mobile friendly images for details.

As discussed earlier, the key to structuring your style sheets is to remain pragmatic. A few additional HTTP requests will impact the overall speed of the website, but if these help you design and structure the markup more effectively, the net result will be a much better user experience.

JJ149683.note(en-us,PandP.10).gifReminder:
Be sure to minify and compress (gzip) all three style sheets to reduce network transfer and download time.

Delivering responsive images

One of the challenges in responsive design is what to do with images. Mobile devices range wildly in screen and viewport dimensions. Your design may be displayed on a 320-pixel feature phone, a 1280- pixel 10" tablet, or on many sizes and devices in between. You therefore need a means to resize images to match the screen size, and in some cases serve different images altogether. The technique you use will depend on how the image is implemented in the app.

Creating flexible inline images

If your image is included inline, within the HTML markup, you can easily render it flexible via the following steps.

This first step is to omit an image size when creating the markup for your inline image.

<img id="chartimage" src="/MileageStats/Chart/chart.png">

Then, apply the following styles to the image.

img {
    height: auto;
    max-width: 100%; 
}

This will create an image with no initial size, but that scales proportionally thanks to the height: auto declaration. Setting the max-width property to 100% ensures that the image will not scale larger than its intrinsic size. Without this setting, there would be nothing to prevent the image from scaling up to match any screen size—even a huge one. In doing so, it would become highly pixelated and the image quality would degrade.

Resizing background images

Background images will not scale naturally, but can be resized (or replaced by entirely new images) using media queries. In this example, an existing background image is sized to a dimension of 16 x 16 pixels once the screen reaches a minimum of 500 pixels in width.

@media all and (min-width: 500px) {
    ol.buttons {
        -webkit-background-size: 16px 16px; 
        background-size: 16px 16px;
    }
}

In this next example, a new image is loaded once the screen reaches a width of 480 pixels, and then is replaced with another once the screen reaches 600 pixels.

@media all and (min-width: 480px) {
    p.intro img {
        background-image:  url('../intro-mid-size.png');
    }
}
@media all and (min-width: 600px) {
    p.intro img {
        background-image:  url('../intro-large.png');
    }
}

Image replacement techniques

The techniques described in the last section enable you to replace a background image via CSS, or create a flexible inline image, but there are many cases in which these changes may not be sufficient to deliver a good experience.

It’s trivial to scale an image, enabling it to fit any screen size. But unless the image was quite large to begin with, it will look progressively fuzzier as it scales up. And given that the largest mobile screens range from 800 to 1280+ pixels (easily resulting in 200KB to 300KB images) it hardly seems fair to subject smaller devices to such a large download.

Automatically resizing images can also impact legibility. This was a big problem for Mileage Stats Mobile as some of our most important images were charts containing text and fine details. Resizing these by as little as 20% resulted in blurred text, and a loss of critical detail. We therefore needed a means of detecting the screen size ahead of time and serving an appropriately sized image to each device.

There are many techniques available for this type of responsive image replacement. Many of these rely on client-side screen size detection, making it difficult to deliver correctly sized images on first load (before the tests have been run and the correct screen size determined). Using client-side, Canvas-based chart rendering for Mileage Stats Mobile would have also overcomplicated our implementation. We therefore needed a means to detect the screen size well ahead of the first load.

See Detecting devices and their features and Delivering mobile-friendly charts for more details.

Note

A detailed explanation of many client-side responsive image replacement techniques can be found in the following articles from Cloud Four in Portland: Responsive images – Part 1 and Part 2 – An in depth look at techniques.

Summary

It is increasingly difficult to make assumptions about the screen sizes and resolutions on devices with web browsers. Instead of offering a different design for each variation, it is more practical to create a single design that responds to the differences. In order to best employ the technique, developers and designers need to understand features of CSS such as media queries.

Next Topic | Previous Topic | Home | Community

Last built: June 5, 2012