Making a web page fit an iPhone screen

When trying to make Today’s Guardian work better on the iPhone I had a strange problem with the pages sometimes being too wide for the device. It took me a while to figure out the solution, and it seems a bit odd, but here’s what I found out.

I’ve made three simplified pages that demonstrate the problem and solution. The basic HTML on all three pages is the same, and looks like this:

<body>
    <div id="wrapper">
        <p>Some paragraphs here...</p>
        <p>More text...</p>
    </div>
</body>

The first example is here. The div#wrapper in this example has this style applied:

width: 600px;

And, in common with many recommendations I’ve seen for getting websites to display properly on the iPhone, the page has this meta tag:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

This causes problems though, as the CSS’s set width seems to take precedence over that meta tag’s “width=device-width” and the page comes out too large. Here’s how it looks — the left shows the page in Safari on an iPhone 3G running iOS4, and the right shows the same page when saved to the Home Screen and opened from there:

First two iPhone screenshots

OK, so we need to fix something. Apple’s Safari HTML Reference guide says this about that meta tag:

If your webpage is narrower than 980 pixels, then you should set the width of the viewport to fit your web content. If you are designing an iPhone-specific web application, you should set the width to the width of the device.

OK, so let’s try our same example page, with the same CSS, but with the viewport meta tag like this:

<meta name="viewport" content="width=600">

Here’s the second example, with the new meta tag, and here’s how it looks, again in Safari on the left, and opened from the Home Screen on the right:

Second two iPhone screenshots

That surprised me. It looks fine opened in Safari — everything fits on the page — but when you save the page to the Home Screen and open it, the page looks different, and no longer fits. Very odd, and I’ve no idea why.

I thought that the Today’s Guardian page, from which this example was derived, worked fine from the Home Screen before I upgraded to iOS4, although I’m not 100% sure. Maybe this is a new problem, unique to iOS4?

Either way, how do we fix it? How do we get a page fitting and filling the iPhone screen, width-wise, when viewed in Safari and when opened from the Home Screen?

There may be other solutions, but the one I found was to set the div’s max-width, rather than its width. So in this third example div#wrapper has this CSS:

max-width: 600px;

And the viewport meta tag looks like this:

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">

This seems to do the trick; here are screenshots, again in iOS4, showing the page in Safari and opened from the Home Screen:

Third two iPhone screenshots

Success!

So that’s good. It’s annoying if you have a block that you want to fill the page entirely but it doesn’t contain much content, so it won’t stretch to its max-width (min-width seems to have the same issues as width). And it’s annoying if you have some JavaScript that manipulates blocks based on their set widths. But, hopefully, nothing too insurmountable.

That second example bothers me though; surely the page should look the same in Safari and when opened from the Home Screen? Why would they be different?

Comments

  • Safari remembers the position that you were zoomed into when you saved the page the first time, even if the page has changed since then. I'd try creating a new homescreen link, after you've made changes to the page, and see if that works. If you were using the old one, it'll be a bookmark not only to the page, but also to the way it was viewed.

    Does that make sense? More to the point, does it help?

  • I'm not quite sure how what you're saying changes anything... in the second example, if I save the Home Screen version I would expect it to look like it does in Safari. But it doesn't. I'm not sure what you mean by making "changes to the page" -- I'm not changing anything.

  • I have explained it rather badly. Let me try again.

    When you save a bookmark in Safari, it just saves a link to the page, and loads it as if it were the first time you'd been on the page.

    However, when you save a link to your homescreen, it not only saves a link to the page, but it also saves the position on the page and level of zoom you were at when you created the link. Unless you recreate the homepage link after you've made the changes to the page you outline above (the changes to the CSS), the homepage link will take you to as close to the position on the page, and level of zoom it was on when you created the homepage link in the first place.

    Does that make more sense?

  • Sorry, I'm still confused. I'm not changing any of the pages -- I have three separate pages, each one a different example. With the second one, if I view it in Safari then the text fits on the page. If I save it to the Home Screen and open it from there then, once the page refreshes (it seems to save a static image of the Safari version which appears momentarily) then the text is too large and wide for the screen.

    I haven't made any changes to that particular page in this process. While testing each of those three, completely separate, examples I'm saving each one separately to the Home Screen, ending up with three icons on my Home Screen.

    Does that make sense? Have I missed something?

  • No, you haven't, it's me being an idiot. Move along here. Nothing to see.

    Sorry!

  • Curious behaviour in your second example. It seems that iPhone web-apps automatically have a scale-factor of 1.0 and disable zooming (even if something different is explicitly specified), which is probably not completely unreasonable, considering that iPhone web-apps would in most cases be optimized for display on an iPhone.

    I'm also not completely sure if i understand what you're trying to do here: have the text fill the whole screen on iPhones, but limit width on iPads to 600px? Have you considered using media queries to distinguish between iPhones and iPads? Something like this:

    @media all and (max-width: 1024px) {
    #wrapper {
    width: 600px;
    }
    }
    @media all and (max-width: 480px) {
    #wrapper {
    width: 300px;
    }
    }

  • At the moment none of this is about iPads, and I haven't tried these examples on them - I just wanted to get consistent behaviour on the iPhone.

  • Here's my stab at an explanation for the differences in example two after some (very limited) testing (iPhone 3G, iOS 4): it seems that an apple-mobile-web-app-capable web page launched from the home screen ignores viewport settings for scale and uses a scale-factor of 1.0, whereas Safari tries to infer the values to make everything fit on the screen. It seems to me that the only way to avoid inconsistencies is to design for a scale-factor of 1.0. Unfortunately I couldn't find any mention of this behavior in the docs. No idea if this is something new to iOS 4 though.

  • Hello!

    This has been driving me nuts for the past week on and off - You're right when you say you suspect this is a v4 issue - I have a little app (www.thinkovation.com/d…) that renders fine in Safari, resizing nicely when you change orientation, and before the OS upgrade it was fine when launched from the home-page. Since the upgrade I've come up against exactly the issue you have.

    Because my app contains sized blocks, I'm still struggling to make your fix work - But will re-comment if I do figure it out.

    In the meantime - Surely this has to be a bug?

  • Hi there,

    I need the html code to disable the pinch zooming on iphone
    Im doing an optimized website for iphone and I need to disable te zoom
    any ideas?
    Thanx guys

  • There's a small anomaly I've found when using "Today's Guardian" in either the Home Screen or in Safari on the iPhone 4 (IOS 4.2.1): sometimes when I swipe to go to the next article the page appears to slide twice into position and it looks like an article has been skipped, but it's just reloaded itself instantly with the sliding motion. It doesn't happen every time but it's a bit disconcerting when it does because I imagine I have missed an article and swipe back only to find I haven't.

    I can't find any consistency in the problem; at one point it looked like it was only happening when I just wanted to skip an article without scrolling down it, but that doesn't happen each time it seems, and it occasionally happens when I've get to the bottom of an article and am swiping to the next page. It sometimes also appears to double load when swiping backwards.

    I have wondered it if could be connected to Guardian ads being loaded at the bottom of the page, as I've noticed them changing while the article is already there?

  • Yes, it is a bit odd. There's also a glitch on the iPad that stops the ability to move forward/backward. I think maybe it's something to do with moving forward/back while the page is automatically scrolling to the top of the page, but that's just a hunch.

    The combination of javascript movements and CSS transforms that do all this seem a bit nasty, but I'm not sure I'll find a solution in the short term I'm afraid.

Commenting is disabled on posts once they’re 30 days old.

6 Jul 2010 at Twitter

  • 7:02pm: Longshadow Southbank is particularly gorgeous.
  • 4:15pm: Off to the BFI Southbank to see Rashomon (for the first time).
  • 2:54pm: "We'll ship to Hazzard County and that alleyway Top Cat used to live in."
  • 2:11pm: Yay, @samuelpepys has just tipped over the 5,000 followers mark. Congratulations Mr. Pepys.
  • 9:51am: Last.fm and Wikipedia are great Bits And Pieces levellers. Otherwise I doubt I'd stand a chance against @mattsheret.
  • 9:28am: Chances of getting work done today diminishing... too busy puzzling over DJ @russelldavies' ongoing "spot the link" music quiz.

6 Jul 2010 in Links

Music listened to most that week

  1. Ikonika (22)
  2. Throwing Muses (13)
  3. The Wolfgang Press (12)
  4. Dinosaur Jr. (10)
  5. Miles Davis (8)
  6. Luscious Jackson (7)
  7. Yazoo (2)
  8. Nick Drake (2)
  9. Prince (1)
  10. Los Campesinos! (1)

More at Last.fm...