Pugetworks
Seattle Software Developers

blog-archive

Pugetworks Blog Archive!

CSS media queries for targeting mobile devices

We've recently worked on a couple of mobile applications with strong webkit components, and as a result I've had plenty of opportunities to explore the ins and outs of CSS3 media queries. Overall, I'm very excited about the possibilities this module offers, but browser support for it has proven buggy and inconsistent. It's not as easy or foolproof as it should be to send different stylesheets to, for example, the iPhone 3g, 4g, and the iPad, and if you throw in the three tiers of Android screen support, things can quickly get complicated.

This document represents a collection of queries I've compiled that allow you to target the major web-capable mobile platforms in use today: The iPhone 3G, 4G, the various Android resolutions, and the newly-arrived Windows Mobile 7. If you need to target any or all of these devices using a single stylesheet (or at most 2), you should be able to do so after reading this article.

How to use Media Queries

A media query is like a CSS selector or a SQL Select statement: it's a syntax for grabbing a few elements from a large set. In this case, you're asking for displays that have (for example) a certain size or resolution. A media query can appear either in the HEAD of an HTML document, or inside a stylesheet. In either case, it will begin with the keyword media followed by the display types and sizes you want to target.

Media queries in the head go anywhere before the closing tag and look like this:

[css] <link rel="stylesheet" type="text/css" media="only screen and (max-device-width: 480px)"> [/css]

Media queries in a stylesheet go anywhere in the CSS file, though you'll typically put them after any styles you want to overwrite, and they look like this:

[css] @media only screen and (max-device-width: 480px) { /* Put your iPhone 3g styles in here */ } [/css]

Both of the above should target exactly the same device (in this case older iPhones with the 320x480 resolution). You don't need to use both, just pick the one that suits your needs best. Use the method if you want to only load certain stylesheets on certain pages, and the Stylesheet method if you don't mind cramming all of your rules into a single file (which makes for faster page loads, all else being equal).

Overwriting CSS styles with media queries

Another thing to remember when serving up @2x images is that if you want the images to be properly proportioned for a 320x480 screen (regardless of DPI) is that you need to use the background-size property in CSS.

iOS devices

4G iPhone (retina display)

The retina display used in the 4g iPhone is differentiated by its high density resolution. You can't use device-height or device-width, because the 4g appears to report itself as 320x480, just like the lower-resolution iPhones and iPods of the previous generation. In a way this is true, it's just that the pixel density is twice as high in the retina display, and you're going to want to give it images that are twice as large or else everything will look blocky.

So, instead of height or width, use the proprietary -webkit-min-device-pixel-ratio attribute to target the 4g. Note that this is a webkit-only query, so don't try to use it on devices with other rendering engines.

[css] @media only screen and (-webkit-min-device-pixel-ratio: 2) { /* Put your iPhone 4g styles in here */ } [/css]

3G iPhones and iPods (320 x 480 pixels)

Target 3G screens with the device-width attribute, as mentioned above.

[css] @media only screen and (max-device-width: 480px) { /* Put your iPhone 3G styles in here */ } [/css]

iPad

Target the iPad with the device-width attribute, rather than max-device-width. You can target iPads in both orientations, or in either portrait or landscape mode.

[css] @media only screen and (device-width: 768px) { /* Put CSS for general iPad layouts in here */ } [/css]

[css] @media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:portrait) { /* Put CSS for iPad PORTRAIT layouts in here */ } [/css]

[css] @media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation:landscape) { /* Put CSS for iPad LANDSCAPE layouts in here */ } [/css]

Android devices

The beautiful and confounding thing about Android is that it supports pretty much any display resolution you can throw at it. This is great for handset manufacturers, but slightly annoying for graphic designers, who will need to make images at several sizes to capture the widest possible audience. It's a lot of fun, let me tell you.

Long story short, Android asks you to create images at three different densities: low, medium and high. You can target each of these very easily with the following media queries.

[css] @media only screen and (-webkit-device-pixel-ratio:.75){ /* Put CSS for low density (ldpi) Android layouts in here */ } [/css]

[css] @media only screen and (-webkit-device-pixel-ratio:1){ /* Put CSS for medium density (mdpi) Android layouts in here */ } [/css]

[css] @media only screen and (-webkit-device-pixel-ratio:1.5){ /* Put CSS for high density (hdpi) Android layouts in here */ } [/css]

Windows Phone 7

As of the writing of this article, WP7's implementation of media queries is limited. They're in there, but you can can't use the initial-scale, maximum-scale, or minimum-scale attributes in a selector, for example, and every WP7 device will report itself as 320px wide, by design.

The good news is that you can always use CSS conditional comments to target Windows Mobile 7 devices only. You're probably already familiar with conditional comments if you do cross-browser design for the web, and it's no different here. Just put the following code in the of your document.

[css] <!--[if IEMobile 7]> <link rel="stylesheet" type="text/css" href="mobile.css" href="mobile.css" media="screen" /> <![endif]--> [/css]

Conclusion

Writing CSS for mobile devices is tricky, no doubt about it. There are a lot of of gotchas, very few robust debugging tools, an exploding market, and a rapidly changing, unevenly supported feature set. It feels like mobile development is where Web development was in about 1997. It could be worse, though: it could be like Web development in 1996.