Combining meta viewport and media queries

If you want to make your websites ready form mobile, it’s best to combine <meta name="viewport" content="width=device-width"> with width media queries. That will give your site the optimal width (as determined by the device vendor, who really ought to know), and your site will look the better for it.

Lanyrd, Simon and Natalie’s latest brainchild, uses exactly this technique, and it establishes the perfect mobile browsing baseline. Try it on as many mobile browsers as you can, and you’ll see. No frills, just a simple user experience that just works.

In order to understand why we should use exactly this combination we should briefly repeat what meta viewports and media queries are all about.

Meta viewport

This is a meta viewport tag:

<meta name="viewport" content="width=device-width">

It sets the browser’s layout viewport, relative to which CSS declarations such as width: 20% are calculated, to the device width.

(Incidentally, Opera has proposed to port this functionality to full CSS, which all in all seems to be a good idea. But for the moment we’re stuck with the HTML tag.)

Normally the layout viewport takes a width that the vendor has decided is optimal for viewing desktop sites.

By setting the meta viewport to device-width you’re sure that your site’s width is optimised for the device it’s being viewed on.

Media queries

The width media query compares the values you feed it to the layout viewport. Thus, if you do this:

body { // basic styles } @media all and (max-width: 600px) { body { // extra styles for mobile } } @media all and (min-width: 600px) { body { // extra styles for desktop } }

the browser measures the layout viewport and applies the desktop styles if it is wider than 600 pixels, and the mobile styles if it’s smaller than that.

If you’d use these media queries without a meta viewport tag they would misfire horribly. Some mobile browsers, notably Safari iPhone, have a default layout viewport of around 850 to 1000 pixels — much larger than the device width. (Why? In order to accomodate desktop sites whose developers did not test on mobile. Such sites usually stretch to roughly that width.)

Thus the example code would conclude the browser is larger than 600 pixels, and apply the desktop styles instead of the mobile ones. Adding the meta viewport tag solves that problem

If you combine a width media query with the meta viewport tag, your site will use the width that the device vendor considers optimal. Although by itself that does not guarantee a perfect mobile experience, it will certainly help.

JavaScript

If you need JavaScript instead of CSS, query document. documentElement. clientWidth . This property contains the layout viewport width.

if (document.documentElement.clientWidth > 600) { // import complicated desktop scripts }

Device width

In theory a device-width media query should do the same, even in the absence of a meta viewport tag. This media query measures the screen width instead of the layout viewport, and that’s what you’re interested in. Isn’t it?

Well, no, it’s not. There are two problems with using device-width instead of the combination of meta viewport and width media query.

Layout viewport not adapted

First of all, there’s the problem I mentioned earlier: some browsers use a layout viewport that’s far wider than the screen width.

device-width correctly reads out the screen width, but once you adapt your layout to this width the page will have a huge right gutter that serves no purpose. After al, the layout viewport is far wider than the device width, and some browsers (notably Safari on the iPhone) will display the full layout viewport, including the useless whitespace on the right.

Screen width !== meta viewport width

The second danger is that the formal screen width is not necessarily equal to the width a meta viewport tag yields. The best example is the Nexus One. The official screen width is 800 pixels, but when you apply <meta name="viewport" content="width=device-width"> it shrinks the layout viewport not to 800 pixels, but to 320 pixels (portrait) or 533 pixels (landscape).

Google did this because the size of the actual, physical pixels on the Nexus One is quite small. Generally that’s good because it gives most applications a crisper look. It’s bad for web development, though: if one such tiny device pixel would be the same as one CSS pixel, most websites would initially be far too small to read, even if the developer set the meta viewport tag.

That’s why Google decided to make the width according to width=device-width smaller than the actual, physical display width. If you add the meta viewport tag the Nexus One will use a layout viewport width of 320 pixels, and not of 800.

For us that means that a device-width media query without a meta viewport tag would misfire: it would adapt the site to an unreadable 800px instead of the Google-approved 320px.

Similarly, the iPhone 4’s Retina display has a far larger physical pixel density than previous iPhones, and its formal pixel density is 960. Still, it reports 320px for the device-width media query (as well as JavaScript screen.width ) both with and without the meta viewport width=device-width .

Although it’s likely that other device vendors will follow Apple’s example and insert the width value they consider optimal into CSS and JavaScript, we can’t be sure of that. Besides, the current browsers do not display this behaviour.

device-width and meta viewport tag

Until now we’ve talked about using the device-width media query without the meta viewport tag. But what if we combine them?

Combining them is perfectly possible on the Nexus One: the device-width media query (and JavaScript screen.width ) adapt to the new pseudo-device-width of 320px. The iPhone 4 always gives 320px anyway, so there’s no problem there, either.

Still, the question remains what the other browsers will do once they abandon their physical pixel count. I, for one, do not dare to gamble on that.

Besides, we’re not interested in the device width. We’re interested in the width of the layout viewport that the device vendor considers optimal. And that means combining a meta viewport tag with a width media query.

Comments are closed.