Getting Started with CSS Media Queries

Getting Started with CSS Media Queries

Tutorials css media queries responsive design tutorial web-design

So over the holidays I finally sat down and rebuilt the CSS on this blog so it doesn't look like garbage on my phone. I've been putting this off since I started techpad back in November, mostly because I assumed it'd be a huge pain, and it turns out it's actually pretty simple once you get the hang of it. The technique is called media queries and if you haven't messed with them yet, you should, because I think this is where web design is headed whether people like it or not.

Quick backstory on why I care: I got a Kindle Fire for Christmas (on top of the iPhone 4S I already carry around) and between the two of them I've got a 7-inch tablet browser and a tiny phone browser both trying to render my site, which was built for a normal 1000px-wide desktop layout. On the Fire it wasn't terrible, but on the phone the sidebar was squeezed down to nothing and the text was basically unreadable without pinch-zooming every paragraph. That's when I decided I needed to actually fix this instead of just complaining about it.

What a media query actually is

At the most basic level, a media query lets you write CSS that only applies when certain conditions are true, usually about the width of the browser window. So instead of building one fixed layout, you build a base layout and then override pieces of it depending on how much screen space you've got. Here's the simplest possible example:

body {
  font-size: 16px;
}

@media screen and (max-width: 480px) {
  body {
    font-size: 14px;
  }
}

That says: normally use 16px text, but if the browser window is 480px wide or less, drop it to 14px. Nothing fancy, but it's the whole idea in one block.

Setting up actual breakpoints

For techpad I ended up with three rough tiers, which seems to be what most people are doing right now (I've seen this same pattern on a few other blogs I read). A "desktop" default with no media query at all, a tablet-ish range, and a phone range:

/* default styles here, this is your desktop layout */

@media screen and (max-width: 768px) {
  .sidebar {
    float: none;
    width: 100%;
  }
}

@media screen and (max-width: 480px) {
  .content {
    padding: 10px;
  }
  h1 {
    font-size: 22px;
  }
}

768px catches most tablets in portrait, 480px catches most phones. Those numbers aren't magic, they're just common enough that using them means your layout probably won't do anything too embarrassing on a random device you haven't personally tested. I picked mine mostly by shrinking my browser window down manually and watching where things started looking bad, which honestly is most of the actual "process."

One thing that tripped me up for an evening: you also need this in your <head>, or none of it works on actual phones:

<meta name="viewport" content="width=device-width, initial-scale=1">

Without that tag, mobile Safari and the Android browser just render the page at desktop width and then shrink the whole thing down to fit the screen, which completely defeats the purpose. I found this out the hard way after spending like forty minutes convinced my media queries were broken when really the phone just wasn't paying attention to them at all.

The catch, obviously

The catch is Internet Explorer. IE8 and below don't understand media queries at all, they just ignore the whole @media block, which for something like techpad is fine since it just falls back to the desktop styles. But if your mobile-first layout depends on the small-screen styles being the default and the desktop stuff being added on top, old IE will just show phone-sized text on a giant monitor and look ridiculous. There are JS polyfills like css3-mediaqueries.js that patch this in, but I didn't bother installing one for a personal blog. Not worth the extra script tag for the three people still on IE8 reading this on a desktop.

I tested the new layout on the iPhone 4S, the Kindle Fire, and my roommate's Galaxy Nexus (that screen is genuinely huge, 720p on a phone still feels a little unreal to me) and it holds up reasonably well on all three. Nothing groundbreaking here, this technique has been floating around for a year or so already, but 2012 feels like the year it stops being optional. If your blog or site still assumes everyone's on a 1024px monitor, that assumption is getting worse every month, not better.

Next thing on my list is figuring out whether to serve smaller images to phones too, since right now everything's just getting scaled down by the browser and that's wasting bandwidth on anyone not on wifi. Haven't cracked that one yet.