Part 11: Intro to Responsive Design
Philosophy
Responsive design is the evolution of a general principal that promotes flexibility and accessibility over “pixel precision.” It has picked up a lot of steam in the past two year as mobile internet use has surged and the debate over the roles of websites versus proprietary apps has raged.
Big media sites often dedicate entire mini-sites to mobile users: sometimes known as the “m dot” approach, these sites display much of the same content as their “desktop” versions, but simplify the layout to a single column, skip the ads and video features, and move the navigation to the top of the page. Take a look at the Guardian mobile, BBC News mobile, or Facebook mobile for examples. The logic used to make a good amount of sense: site developers knew that mobile phones have low-resolution screens, expensive internet access rates, and that users would be in a hurry to see the content, preferably unadorned by a desktop-optimized design. Therefore, they reason, those users should be re-directed to a separate “mobile experience” specifically tuned to their needs.
But this logic has started to fall apart in recent years. What about tablet computers — are they “mobile”? Should iPad users be sent to mobile-optimized sites or given the desktop version? What about iPod touches connected via wifi, which have high bandwidth and higher resolution screens than computers from the mid-90s? For that matter, why should desktop computer users always get image-heavy versions of the site? Things get even more problematic when developers have to manage multiple URLs that serve up similar content: when a desktop user emails a link (e.g. http://nytimes.com/obama-article
) and it is opened by a mobile user, should it redirect to http://m.nytimes.com/obama-article
? What if content the desktop user was referring to is now missing? And what about search engines — should the mobile versions of all pages be hidden from them, so they don’t water down the SEO value of the desktop URLs?
Responsive design does not answer all of these questions, but it certainly takes a new approach: We shouldn’t slice our website up into multiple versions based on our guesses about the needs that go with particular devices: after all, the mobile user might well want the “full” experience, while the desktop user might still be on dial up or like to keep his or her browser window skinny.
It is better and simpler, the argument goes, to create a single website that adapts to particular features of the user’s software. This is distinct from the discredited practice of using Javascript to “sniff” the user’s particular browser or OS, since feature detection is “future compatible”: that is, it is likely to keep working as new versions of the browsers are introduced. Jeremy Keith explains this argument well in his post One Web.
As described by designer/developer Ethan Marcotte, today responsive design can take advantage of at least three techniques: (1) a flexible grid design, (2) images that scale, and (3) media queries. Combining the three techniques enables the layout of a site to adapt to radically different browser widths.
Step 1: The Flexible Grid
It is common to use a grid system to organize information into a set of visually-pleasing columns. Like print designers, web designers often like to use particular mathematical relationships to create their grid: a sidebar’s width might be a half or a third of the main column’s width, and then contain elements that are each half of that width. (See the 960 grid system for one popular framework).
Suppose you design such a layout using a series of floated div
containers, each set to pixel widths. (You probably would not set any heights with CSS, but instead allow the content to define the height of each div
). Your HTML outline might look like this:
<div id="content">
<div id="main">
[content]
</div> <!-- /main -->
<div id="side">
<div id="bio">
[content]
</div> <!-- /bio -->
<div id="links">
[content]
</div> <!-- /links -->
</div> <!-- /side -->
</div> <!-- /content -->
And your CSS might look like this
content {float:left; width:800px;}
#main {float:left; width:475px;}
#side {float:right; width:300px;}
#bio {float:left; width:145px;}
#links {float:right; width:145px;}
Creating a “flexible grid” means converting those pixel values to percentages. But first, we need to set an overall maximum width for our page, to prevent lines of text from getting too long. So even though our pixel-width for content
was 800 px, we might choose a larger maximum value for the flexible design.
#content {max-width: 1200px}
Now we dive into the main work of converting container widths from pixels to percentages. The key point here is that you must always calculate the percentage based on the parent container of your element. In other words, when we set the width of <div id="bio">
, we should divide 145 px by 300 px (since side
is its parent), not by 800 px. Ethan Marcotte describes the formula as follows: target รท context = result, where “context” means the parent container. Following this procedure, we get the following:
content {float:left; max-width:1200px;}
#main {float:left; width:59.4%;}
#side {float:right; width:37.5%;}
#bio {float:left; width:48%;}
#links {float:right; width:48%;}
I’ve left out margins for simplicity, but they follow the same rules. margin-right:10px
on the main
div would come out to margin-right: 8%;
This is already a much better web layout: users with Cinema Displays will actually get the benefit of having such a large screen, while iPad users won’t have to scroll sideways or zoom in and out.
Step 2: Allowing Images to Scale
Images, of course, have defined dimensions by default: for a responsive design, you will usually embed relatively large-size images in your pages (maybe 1000 px wide), and then allow the browser to scale them down as needed. To allow images to scale, we first need to remove any height and width attributes from the image tags themselves, since they will prevent the scaling from working: So <img src="myphoto.jpg" alt="My photo" width="200" height="100" />
becomes <img src="myphoto.jpg" alt="My photo" />
. (Both versions are valid XHTML, though only the former allows the browser to draw the shape of the image before it has entirely loaded).
Second, we need to write a max-width
declaration for images that we want to scale. The beauty of max-width
is that it scales the images down when their container gets skinny (100% means 100% of the container), but it doesn’t scale the image up when the container gets very wide (which would cause pixelization). So we target the content images with a CSS rule:
#content img {
max-width:100%;
}
Step 3: Adding Media Queries
Even a flexible grid, however, starts to break down as the browser gets extremely skinny. Media queries — a CSS3 technique — come to our rescue here. This special syntax allows us to change the layout based on the browser’s width. We can therefore create three (or four, or five…) layouts that kick in at particular widths. And since our design is percentage-based, the site will continually adapt itself to the browser within each of these layouts.
Media queries use a strange syntax and add an extra nesting of curly braces, but if you follow the format below, you should be able to get them working. And because they contain regular CSS rules, you are free to change any element (such as font-size) for any of the layouts.
Here we just use media queries to turn off floats and change widths, creating a two-column layout optimized for smaller screens and a single-column layout optimized for phones.
content {float:left; max-width:1200px;}
#main {float:left; width:59.4%;}
#side {float:right; width:37.5%;}
#bio {float:left; width:48%;}
#links {float:right; width:48%;}
/* Begin medium, two-column layout */
@media screen and (min-width: 601px) and (max-width: 800px) {
#bio, #links {float:none; width:100%;}
}
/* end two-column layout*/
/* Begin single-column layout */
@media screen and (max-width: 600px) {
#main, #bio, #links, #side {float;none; width:100%;}
}
}
It’s important to note that these techniques are only part of the picture, and “responsive design” may end up meaning different things for different websites. More importantly, there are techniques still being developed that will help responsive design live up to its own philosophy: chief among these are techniques for serving up images appropriate to the size at which they will be rendered, rather than wasting bandwidth by serving very large images to all users.
Bonus Round
Safari for iOS (aka “MobileSafari”) assumes that websites are 980 px wide, which will usually defeat the “small screen” media query you write. To fix it, put the following meta tag in the <head>
of your pages:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Further Reading
- Exercise 18
- Responsive Web Design, by Ethan Marcotte.
- Fluid Images, by Ethan Marcotte.
- Experimenting with responsive design in Iterations, by Diy Solar
- Context, by Jeremy Keith
- One Web, by Jeremy Keith.
- Controlling text size in Safari for iOS without Disabling User Zoom