Media queries are an amazing tool that front-end developers have at their disposal these days, but I think most front-end developers who decide to dig into media queries aren’t ready to completely eschew the way they’ve been working. In my case, as with many, I’ve grown accustomed to designing and coding to some sort of grid which is usually around 960px wide. As a result, when trying to add in @media queries to my workflow, my first instinct was to start with one of those fixed-width designs and figure out how to scale it down. Using the @media rule plus ‘max-width’ allows us to do this. (If you need a quick primer on @media queries, this is a good start.) Starting from a site that is 960px wide, if we want to make it scale down for a smaller screen we can do something like this:
#container {
width: 960px;
margin: 0 auto;
background: #ccc;
}
@media only screen and (max-width: 480px) {
#container {
width: 100%;
background: #aaa;
}
}
View Example 1 – Resize browser to see it in action
We’ve defined our styles for the ‘main’ resolution, and overridden them inside the @media query for all screen resolutions up to a maximum width of 480px. So we’ve got two places in our css where we’ve defined the width of #container. This totally works but if you do it a few times you quickly realize this is not very efficient and starts to feel like a lot of redundant work. For example, lets say you have a 2 column block, each element floated within it with a width set on each one. (Notice I’ve changed ‘width’ to ‘max-width’ on the #container. This gets us closer to a fluid/responsive layout. Resize and you’ll see.)
#container {
max-width: 960px;
margin: 0 auto;
background: #ccc;
overflow: auto;
}
section {
width: 70%;
float: left;
background: #eee;
}
aside {
width: 30%;
float: left;
background: #bbb;
}
@media only screen and (max-width: 480px) {
#container {
width: 100%;
background: #aaa;
}
section,
aside {
width: 100%;
}
}
View Example 2 – Resize browser to see it in action
Inside the @media block targeting smaller screens, we’ve overridden all of the values set for the larger screen. In this case it would mean re-setting float, width, and in a real world example things like padding, margin and backgrounds. Why should we do this when can take advantage of the natural state of these elements? All block-level elements, by default, are not floated and have a default width of 100% and this is usually what you want to serve up to the smallest screens, since there’s usually not room to have stuff floated all over the place.
Interested in more than just height-based media queries? Join us at BDConf in Nashville, June 19-20, 2015, for a unique look at the future of mobile design.
A better way
Instead of starting big and using ‘max-width’ to hack away, a better approach is to start small and ‘min-width’ to target ever larger devices. As opposed to ‘max-width’, ‘min-width’ says ‘apply these styles to all screens that are greater than whatever value’.
The way it works in practice is that we can put all of the baseline styles at the top of your css, outside of the @media queries. This is where you can define your basic typography, colors and your general hierarchy. Then for each @media rule you can add as screens get larger. Using @media with min-width we end up with something like this:
#container {
background: #aaa;
}
section {
background: #eee;
}
aside {
background: #bbb;
}
@media only screen and (min-width: 480px) {
#container {
max-width: 960px;
margin: 0 auto;
background: #ccc;
overflow: auto;
}
section {
width: 70%;
float: left;
}
aside {
width: 30%;
float: left;
}
}
View Example 3 – Resize browser to see it in action
The end result of the last two examples is functionally identical, but using min-width is a much more elegant solution. Notice that that the background colors are being set just to show a difference between the elements. There isn’t anything at the top of the css in regards to layout. Starting small with min-width reduces redundancy and enables you to focus on structuring your markup logically. It also ensures that many more screen and form factors are taken into account from the beginning as opposed to being an afterthought. Another bonus is that for devices that may not support media queries, you can still serve up a base set of styles that will more likely work that a full site.
Honestly it took me a while to wrap my head around this concept. So in preparation for this article I worked up this little demo that shows it in action.
View Responsive Demo using @media and min-width
For more information on a similar topic, check out Mobile First by Luke Wroblewski and make sure to read Ethan Marcotte’s book Responsive Web Design.
Shaweet. Useful technique!
Great article – love the colors in the final demo too. One thing, and I might have this backwards, but in the second sentence under A Better Way heading I think you mean: “As opposed to ‘max-width’, ‘min-width’ says ‘apply these styles to all screens that are GREATER than whatever value’.” ?
Lucy, you’re correct. Thanks for catching that! I’ve corrected that line.
Thanks so much for this lovely tutorial. I greatly enjoyed the demo too! I think in the end it /is/ better to start small then build up. I’ve been having trouble using max-width after building a full website, but I know how to utilise this now going forward. Thanks again Jay!
Great post man! You explain Media queríeis in a Very simple war. Saved in bookmarks!
have a little buggaroo in your media query css with the search button: http://localhostr.com/files/zBlQTrC/Screen+Shot+2012-07-23+at+5.01.40+PM.jpg
nothing huge, but just thought I would let you know 🙂
Hi there, very nicely demoed.
The only problem is that Media Queries are not accurate.
It is not your fault obviously, but I wish people would talk about that, too.
It is easy to check with window size plug in and your demo (or any other site that uses MQ).
Some times they are off only 20 pixels but other time they are off up to 150 pixels… However, even 20 pixels is very bad when trying to target a certain mobile phone screen.
Awesome article. Thank you for putting it together. Would you have to use javascript to introduce HTML elements for larger layouts? For example, say I have a utility nav that’s only visible when browser size is > 1000, I would need to insert the html via javascript as I don’t want that extraneous code in the mobile environment. Is that correct, or am I missing something?
Thanks for the simple, direct and effective method. Very elegant and compact without all the fluff I don’t need.
This is a nice tutorial but sorry to say that not working in IE8
Download broken.
Loved this! Is the download no longer available?
Great demonstration! This is sooooo useful for anyone learning CSS3 to create responsive sites! The demonstration works a treat and thank you so much for putting some “frequently used” device sizes!
veri good this tutorial…
Thanks these examples are really cool!
Finally. A simple, humble, straight-forward explanation from someone not claiming theirs is the one right way to do things. You laid out both cases so readers can decide. My mind automatically thinks like the first example (big to small), but now I clearly see the advantages of the second example (small to big). Thank you!
unique example and Guide………………………. it’s beginners need, but can’t be downloaded…..
How do you call different stylesheets based on the width in HTML for example to have a stylesheet called phone.css another called laptop.css, desktop.css, etc.
How do you do so?
Thanks Brother. Good Tutorial