Controlling text size in Safari for iOS without disabling user zoom

The default viewport settings—the size and scale of the viewport—in Mobile Safari/Safari for iOS are optimised for websites with a width of 980 pixels. This means that if you use a fluid/elastic layout or media queries to make your layout adaptable, Safari on iOS doesn’t take advantage of the flexibility that offers but shows the site zoomed out as if it had a fixed width.

Another issue with Safari on iOS is how text size is handled when you change orientation from portrait to landscape on your iPhone/iPod/iPad. The default behaviour is to increase text size instead of using the extra available width to display more of the site.

As a developer you can affect both of these issues (or features if you prefer to call them that).

Setting viewport width

To stop Safari on iOS from assuming that your site is 980 pixels wide, you can use a meta element to set the viewport width:

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

What this does is tell the browser that it should use a viewport width equal to the device’s physical width. As long as your layout is fluid or you use media queries to provide different layouts for different viewport widths this will make your site fill up the viewport nicely without the user having to zoom in to see the text.

Preventing auto-scaling of text

Preventing Safari on iOS from increasing text size when the orientation is changed from portrait to landscape is a bit more tricky if you want to do it without completely disabling user zoom (which you do).

It is fairly common to see the following:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />

In addition to setting the viewport width, this sets the initial and maximum scales to 1 and completely disables user scaling (in practice this is what maximum-scale does as well). Disabling user scaling is a pretty serious drawback and not something I would recommend. initial-scale=1 is useful though since as far as I can tell from Apple’s documentation (How Safari Infers the Width, Height, and Initial Scale) it’s meant to keep things the same size when changing orientation.

Unfortunately it does not work that way—changing orientation from portrait to landscape scales the page up. This seems like a bug and has been reported to Apple—see a bug report and test case for the scaling bug.

In the meantime there is a workaround that needs the initial-scale property, so here is what I recommend:

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

On its own, this does not prevent Safari’s auto-zoom. You also need to use the -webkit-text-size-adjust CSS property (which I posted a warning about in Beware of -webkit-text-size-adjust:none).

By setting -webkit-text-size-adjust to 100% instead of none Safari keeps the same text size after an orientation change, while still allowing the user to zoom in if they need to. Setting it to 100% also seems to leave user resizing of text alone unlike none.

In a perfect world, both problems would be solved by putting this in your HTML:

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

and this in your CSS:

body {-webkit-text-size-adjust:100%;}

But this is not a perfect world, unfortunately. As I have already mentioned, Safari still auto-zooms when you change the orientation to landscape. However when you pinch the page to zoom out, the text scales down and snaps to the same size as in portrait orientation. Adding maximum-scale=1 to the viewport meta element removes the need for this, with the—in my opinion—showstopping drawback of completely disabling user scaling. Please don’t do that.

It’s your choice, but I recommend putting the user first

It basically comes down to two choices:

In most cases I would really recommend the latter option. Before choosing to disable user scaling, consider if your users seeing the same text size after changing the orientation of their device really is more important than them being able to zoom in if they need to.

Posted on December 21, 2010 in iOS, Usability, CSS