Responsive Web Design: Baby Steps

So you’re ready to take the plunge into responsive web design? Well hold on there, partner. Your enthusiasm is good but let’s make sure we’ve done our homework, too. First things first, make sure you have the following development essentials:

  • Fresh coffee: keep that enthusiasm going.
  • Good music: creativity needs good mojo.
  • A comfy chair: your backside will thank you.

Ready now? Ok, let’s dive in.

Step #1: Layout

Whether you’re building a new site or rebuilding an old one, the page layout is critical to a solid responsive design. Some layouts will be more conducive to responsive design than others. Starting with a grid-based layout will give you a lot of flexibility. If you want something lighter weight, a simple floating-column layout will also work well. For reference, let’s start with a typical fixed-width, two-column layout:

layout.html
<!DOCTYPE html>
<html>
	<head>
		<title>Fixed-Width, Two-Column Layout</title>
		<link rel="stylesheet" type="text/css" href="styles.css">
	</head>
	<body>
		<div id="page">
			<header id="page-header">
				<h1>This is the header</h1>
			</header>
			<div id="page-body">
				<div id="content">
					<h2>This is the page content</h2>
				</div>
				<div id="sidebar">
					<h3>This is the page sidebar</h3>
				</div>
			</div>
			<footer id="page-footer">
				<h4>This is the footer</h4>
			</footer>
		</div>
	</body>
</html>

You’ve probably noticed the use of HTML5. This isn’t strictly necessary, but it’ll put you in good position for implementing advanced features. Trust me, you’ll be glad you did it. Other than that, this is about as simple as it gets. Now, here’s the accompanying stylesheet:

styles.css
html, body {
	background: #666;
}
h1, h2, h3, h4 {
	margin: 0px;
	padding: 10px;
}
#page {
	width: 1280px;
	margin: 20px auto;
}
#page-header {
	background: #069;
	color: #fff;
}
#page-footer {
	background: #069;
	color: #fff;
	font-size: smaller;
	text-align: center;
}
#page-body {
	overflow: hidden;
	background: #fff;
	color: #333;
}
#content {
	overflow: hidden;
	float: left;
	width: 960px;
}
#sidebar {
	overflow: hidden;
	float: right;
	width: 320px;
	background: #ccc;
}

Still pretty straight-forward. The net result is a fixed-width page with the main content in the left-hand column and a sidebar on the right-hand column. Notice the #content and #sidebar elements have properties float: left; and float: right;, respectively. To move the sidebar to the left-hand column, you can simply switch the left and right floats. Be careful, though, not to switch the order of the html tags in the layout. The order will be important when we get to modifying the design for different screen sizes. Also notice the overflow: hidden; property on the #page-body, #content, and #sidebar elements will prevent the content from making a mess of our column widths. Ok, so far, so good.

Step #2: Media Queries

Now that we have our layout built, we’re ready to work a little voodoo. The key here is to choose the screen widths we want to adjust our layout for and implement them using the CSS @media element. For instance, if we want to design around the iPhone, the screen widths we’ll be dealing with are 320 pixels (portait) and 480 pixels (landscape). If we also include the iPad, we’ll also want to account for 768 pixels (portrait) and 1024 pixels (landscape). That means we now have four alternative screen widths to deal with, which will mean four media queries in our CSS. Let’s start with 1024 pixels, the widest layout and closest to our original width of 1280 pixels. We’ll add the following lines to our stylesheet:

styles.css (continued)
@media only screen and (min-width: 1024px) and (max-width: 1279px) {
	#page {
		width: 1024px;
	}
	#content {
		width: 768px;
	}
	#sidebar {
		width: 256px;
	}
}

The first thing you should notice is the min-width and max-width properties in the media query. What this does is applies everything in the block as an override to our main stylesheet, but ONLY to screens with widths between 1024 pixels and 1279 pixels. Once the screen width reaches 1280 pixels, our media query no longer applies and our main stylesheet takes over. Try resizing your browser window and watch our layout snap back and forth between our two widths. Of course, once your screen width drops below 1024 pixels, the layout reverts to its default 1280 pixels. Obviously this isn’t what we want, so let’s fill in the rest of our alternative screen widths:

styles.css (continued)
@media only screen and (min-width: 768px) and (max-width: 1023px) {
	#page {
		width: 768px;
	}
	#content {
		width: 512px;
	}
	#sidebar {
		width: 256px;
	}
}
@media only screen and (min-width: 480px) and (max-width: 767px) {
	#page {
		width: 480px;
	}
	#content, #sidebar {
		float: none;
		width: 480px;
	}
}
@media only screen and (max-width: 479px) {
	#page {
		width: 320px;
	}
	#content, #sidebar {
		float: none;
		width: 320px;
	}
}

There we go, all of our alternative screen widths are now accounted for. Notice that on our last media query, we only include a max-width. Leaving off the minimum width on our narrowest layout will apply that layout to anything smaller than 320 pixels, instead of the default layout. You should also notice that on the 480-pixel and 320-pixel layouts, we apply the float: none; property to the #content and #sidebar elements, as well as setting them both to the full page width. This will stack them on top of each other instead of laying them out side-by-side. Now, remember when I told you the order of elements in the HTML would become important? Here it is: if we had put the sidebar before the main content in our HTML because we wanted the sidebar on the left-hand side, we would end up with the sidebar above the main content in our smaller layouts. See? I told you so.

Now we can’t call it a day until somebody throws us a curveball. Today it’s the iPad. The iPad is going to pull a little prank on us by scaling its pixels and rendering our portrait layout, even in layout orientation. Fortunately for us, correcting this behavior is pretty simple. Adding the following element to the <head> section of layout.html will prevent pixel scaling and we can all go home happy.

layout.html (continued)
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">

So that’s that. Obviously, we could dig a whole lot deeper into responsive design, but for today we’re taking baby steps. Rome wasn’t built in a day and neither are great websites, but today you’ve taken your first steps into a brave new world. So give yourself a pat on the back and have some fun with your new tools.