Screen resolution nowsaday ranges from 320px (iPhone) to 2560px (large monitor) or even higher. Users no longer just browse the web with desktop computers. Users now use mobile phones, small notebooks, tablet devices such as iPad or Playbook to access the web. So the traditional fixed width design doesn't work any more. Web design needs to be adaptive. The layout needs to be automatically adjusted to fit all display resolution and devices. This tutorial will show you how to create a cross-browser responsive design with HTML5 & CSS3 media queries.
See It in Action First
Before you start, check the final demo to see how it looks like. Resize your browser to see how the layout automatically flows based on the width of the viewport (browser viewing area).
More Examples
If you want to see more examples, check out the following WordPress themes that I designed with media queries: Tisa, Elemin, Suco, iTheme2, Funki, Minblr, and Wumblr.
Overview
The page's container has a width of 980px which is optimized for any resolution wider than 1024px. Media query is used to check if the viewport is narrower than 980px, then the layout will turn to fluid width instead of fixed width. If the viewport is narrower than 650px, it expands the content container and sidebar to fullwidth to form a single column layout.
HTML Code
I'm not going to go through the details of the HTML code. Below is the main structure of the layout. I have a "pagewrap" container that wraps the "header", "content", "sidebar", and "footer" together.
<div id="pagewrap">
<header id="header">
<hgroup>
<h1 id="site-logo">Demo</h1>
<h2 id="site-description">Site Description</h2>
</hgroup>
<nav>
<ul id="main-nav">
<li><a href="#">Home</a></li>
</ul>
</nav>
<form id="searchform">
<input type="search">
</form>
</header>
<div id="content">
<article class="post">
blog post
</article>
</div>
<aside id="sidebar">
<section class="widget">
widget
</section>
</aside>
<footer id="footer">
footer
</footer>
</div>
HTML5.js
Note that I use HTML5 markup in my demo. Internet Explorer prior than version 9 doesn't support the new elements introduced in HTML5 such as <header>, <article>, <footer>, <figure>, etc. Including the html5.js Javscript file in the HTML document will enable IE to acknowledge the new elements.
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
CSS
Reset HTML5 Elements to Block
The following CSS will reset the HTML5 elements (article, aside, figure, header, footer, etc.) to block element.
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block;
}
Main Structure CSS
Again, I'm not going to get into the details. The main "pagewrap" container is 980px wide. Header has a fixed height 160px. The "content" container is 600px wide floated left. The "sidebar" content is 280px wide floated right.
#pagewrap {
width: 980px;
margin: 0 auto;
}
#header {
height: 160px;
}
#content {
width: 600px;
float: left;
}
#sidebar {
width: 280px;
float: right;
}
#footer {
clear: both;
}
Step 1 Demo
Here is the design demo. Note that the media queries haven't been implemented yet. Resize the browser window and you should see that the layout is not scalable.
CSS3 Media Query Stuffs
Now here comes the fun part — media queries.
Include Media Queries Javascript
Internet Explorer 8 or older versions doesn't support CSS3 media queries. You can enable it by adding the css3-mediaqueries.js Javascript file.
<!--[if lt IE 9]>
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->
Include Media Queries CSS
Create a new stylesheet for the media queries. Check out my previous tutorial to see how media queries work.
<link href="media-queries.css" rel="stylesheet" type="text/css">
Viewport Smaller Than 980px (Fluid Layout)
For viewport narrower than 980px, the following rules will apply:
- pagewrap = reset width to 95%
- content = reset width to 60%
- sidebar = reset width to 30%
Tips: use percentage (%) value to make the containers fluid.
@media screen and (max-width: 980px) {
#pagewrap {
width: 95%;
}
#content {
width: 60%;
padding: 3% 4%;
}
#sidebar {
width: 30%;
}
#sidebar .widget {
padding: 8% 7%;
margin-bottom: 10px;
}
}
Viewport Smaller Than 650px (One-Column Layout)
Next I have another set of CSS for viewport narrower than 650px:
- header = reset height to auto
- searchform = re-position the searchform to 5px top
- main-nav = reset the position to static
- site-logo = reset the position to static
- site-description = reset the position to static
- content = reset the width to auto (this will make the container to expand fullwidth) and get rid of the float
- sidebar = reset width to 100% and get rid of the float
@media screen and (max-width: 650px) {
#header {
height: auto;
}
#searchform {
position: absolute;
top: 5px;
right: 0;
}
#main-nav {
position: static;
}
#site-logo {
margin: 15px 100px 5px 0;
position: static;
}
#site-description {
margin: 0 0 15px;
position: static;
}
#content {
width: auto;
float: none;
margin: 20px 0;
}
#sidebar {
width: 100%;
float: none;
margin: 0;
}
}
Viewport Smaller Than 480px
The following CSS will apply if the viewport is narrower than 480px which is the width of the iPhone screen in landscape orientation.
- html = disable text size adjustment. By default, iPhone enlarges the text size so it reads more comfortably. You can disable the text size adjustment by adding
-webkit-text-size-adjust: none; - main-nav = reset the font size to 90%
@media screen and (max-width: 480px) {
html {
-webkit-text-size-adjust: none;
}
#main-nav a {
font-size: 90%;
padding: 10px 8px;
}
}
Flexible Images
To make the images flexible, simply add max-width:100% and height:auto. Image max-width:100% and height:auto works in IE7, but not in IE8 (yes, another weird IE bug). To fix this, you need to add width:auto\9 for IE8.
img {
max-width: 100%;
height: auto;
width: auto\9; /* ie8 */
}
Flexible Embedded Videos
To make the embedded videos flexible, use the same trick as mentioned above. For unknown reason, max-width:100% (for embed element) doesn't work in Safari. The work around is to use width:100% instead.
.video embed,
.video object,
.video iframe {
width: 100%;
height: auto;
}
Initial Scale Meta Tag (iPhone)
By default, iPhone Safari shrinks HTML pages to fit into the iPhone screen. The following meta tag tells iPhone Safari to use the width of the device as the width of the viewport and disable the initial scale.
<meta name="viewport" content="width=device-width; initial-scale=1.0">
Final Demo
View the final demo and resize your browser window to see the media queries in action. Don't forget to check the demo with the iPhone, iPad, Blackberry (newer versions), and Android phones to see the mobile version.
Summaries
- Media Queries Javascript Fallback:
css3-mediaqueries.js is required to enable media queries for browsers that don't support media queries.<!--[if lt IE 9]> <script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]--> - CSS Media Queries:
The trick for creating an adaptive design is to use CSS to override the layout structure based on the viewport width.@media screen and (max-width: 560px) { #content { width: auto; float: none; } #sidebar { width: 100%; float: none; } } - Flexible Images:
Use max-width:100% and height:auto to make the images flexible.img { max-width: 100%; height: auto; width: auto\9; /* ie8 */ } - Flexible Embedded Videos:
Use width:100% and height:auto to make the embedded videos flexible..video embed, .video object, .video iframe { width: 100%; height: auto; } - Webkit Text Size Adjust:
Use -webkit-text-size-adjust:none to disable text size adjust on the iPhone.html { -webkit-text-size-adjust: none; } - Reset iPhone Viewport & Initial Scale:
The following meta tag resets the viewport and inital scale on the iPhone:<meta name="viewport" content="width=device-width; initial-scale=1.0">
Will the custom CSS upgrade in WordPress.com recognize the @media tag?
can you recommend a nice fluid 100% width design idea? hard to find any design example anywhere (besides large image background websites) that have a nice left menu all the way on the left..
Terrific tutorial. Thanks for sharing.
really nice tutorial..this is really exactly what i need..thank you so much..
Nice example, however, on my ipad 2, running the latest safari browser.
It all starts good, but when you rotate to portrait mode and go back to landscape, the layout is too wide. in otherwords, the sidebar does not show.
There is something wrong with the scaling I assume. As when i refresh the layout is smaller than when I rotate the screen.
Any idea how to fix that?
thanks
A month late but if anyone is reading this comment and looking for the answer: http://webdesignerwall.com/tutorials/iphone-safari-viewport-scaling-bug
Really great article by the way! as always
Thanks for the nice tutorial. I hope can build the same responsive theme taking something out of this.
Why isn’t it working on my brand new blackberry 990.
Beta.somvio.com is a responsive theme which works on my blackberry but http://webdesignerwall.com/demo/adaptive-design/demo-step1.html doesn’t work… What did you do differently?
That url links to the first step in the tutorial that does not contain any @media calls.
look at the finished demo to see it work.
Fantastic and thougher tutorial. Thanks for sharing it.
As always with this site, all I can say is props to you sir for yet another insightful breakdown of important CSS/design concepts
For god’s sake, man: this is good stuff!
Hi,
Thanks for such a wonderful tricks. Here i have a question and forgive me if Im making no sense in my words :)
For the responsive designs, do I only need to first create a general design as we do normally from PSD to XHTML and thn use the above additions/tricks to make it working?
Thanks,
Jason
… and print….
Just come to this page from your Responsive Design in 3 Steps and both were worth the read. I appreciate how clearly this has been written and it provides a useful basis in understand the basics of responsive design. Thank you.
I’m curious as to why you’re not using modernizr which has respond.js built in. Modernizr also allows IE to read html5 correctly.
Some good reasons I can see:
respond.js has just been stripped out of the Modernizr builder (citing performance concerns): https://github.com/Modernizr/Modernizr/issues/348
Also, because these 2 scripts (the shiv and media query support) are loaded as IE conditionals, they will not add unnecessary extra filesize to the page load on modern browsers (since they will skip past those links).
That’s assuming you don’t need the extra tests that Modernizr can provide, of course.
when i study it. i only want to say from bottom of my heart thanks a lot guys. u guys rocks. free html/css helps me a lot to learn a responsibe design from scratch. I’m lovin in it. keep sharing. once again thnks a lot….
WOW!! – I am late to the responsive design party and this is the first tutorial I found on Google – so glad I did – it’s an excellent and clear introduction for me. I intend to use and adapt this for one of my sites in the next week or so. Thank you.
I am creating some wordpress theme and your tutorial helps me.
The one thing that I need that wasn’t covered is how to either make certain elements disappear or replace them with others (such as replacing a nav menu with a dropdown list).
Fantastic tutorial otherwise!
very detailed this is what I’m looking for.. I’m tasked to create a responsive layout and I think this is solution.. thank you so much mate.. :)
I have read several just right stuff here. Certainly value bookmarking for revisiting. I wonder how a lot effort you put to create this sort of magnificent informative web site.