It seems that browser writers are adding ‘features’ to deal with the proliferation of abominably wide or fixed-width sites. Mobile Safari, as supplied on the iPhone, supports a zoom feature for its 320×480 screen, whose image can famously turn to match the orientation of the device. Here's how it appears to work:

This works fine if the area of interest itself has a limited width, such as a news column alongside others that together make the page as a whole quite wide. Zooming in makes the text readable in terms of font size, while the limited width ensures that the line length does not exceed the physical screen size at this level of scaling.

But no page is required to have any width limitation applied to it by the author. By design, that limitation is supposed to be made only at the point of rendition. When Mobile Safari tries to show an unstyled page, it allows it to fill the 980 pixels of its virtual space, but then is forced to shrink it to show the whole page. If the user zooms in to read the text, the lines no longer fit the screen, and the page becomes difficult to use.

Effectively, this feature has made all the well-designed pages invalid, just to cope with badly designed ones better, pandering to their designers' insane fixed-width cravings. This clever feature of coping with pages that demand more space than the browser initially offers, has been broken by being uncleverly configured to initially claim to offer more real space to a page than it has available. It should initially offer exactly as much virtual space as it has real space available.

The <meta> solution?

Apparently, the author of a well-designed page can add a <meta> element to tell (only) Mobile Safari to offer less space than the default 980:

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

But if Mobile Safari can cope with pages wider than 980px when that is its minimum, it ought to be able to cope with them just as well if it initially offers something much narrower. Why doesn't it simply use 320px as its default instead? (I assume that medium text in a virtual image of that size is readable at the default zoom level; if not, re-configure minimum virtual image size or the default font size by an appropriate factor.)

You could argue that authors are responsible for routinely adding the <meta> al ĉiuj iliaj paĝoj se ili postulas ke tiuj funckiu sur iPhone, but:

  • No! They are only responsible if they diverge from defaults.

    A page that is already width-agnostic should not have to sacrifice that just to work well in an iPhone.

  • What size should they specify? What happens to the page when viewed with the next version of the device (or a rival) with a 20% bigger screen? The browser is best placed to know what is a good default minimum, so let it specify.

    Solving the problem just for one particular browsing environment is not scalable.

There is no need for an author to specify a width, because the virtual-image mechanism above copes fine with pages that demand more width than it offers by default. Just get the default right in the first place! Reconfiguring the device to a more ‘honest’ default will make width-agnostic pages display better, while not breaking the fixed-width and width-hungry sites.

To demolish my thesis, you need to find a site that operates better in a configuration other than 320px as an initial virtual viewport width. Here's how to do a test:

  • Download the raw HTML of the page. You could download the images too, but it's not normally necessary.

  • Edit the file so that it contains the following line at the start of the <head> element:

    <base href="the page's address">
    

    You need to fill in the page's real address, of course.

  • Elsewhere in <head>, find a <meta> viewport element:

    <meta name="viewport" content="something">
    

    If it doesn't exist, simply add it with the following setting:

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

    Otherwise, set it to that.

  • Make sure there are no other <meta> viewport settings.

  • Publish the page somewhere so you can view it with an iPhone, and compare it with the original page.

You might notice a difference during loading, but is the original better than the adjusted copy when the page is fully rendered?

Update, 2011-01-23: It seems that there is a straight-forward solution to this problem using the <meta> element above:

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

Yay! Now you can set the viewport width to the actual device width! Why isn't this the default? I shouldn't have to set it on all my websites. Oh well, at least it's width-agnostic.

The idw solution?

What if we want to exploit the zoom feature offered by the iPhone to do complex layouts, while still providing simple layouts for unavoidably narrow media? This requires that the browser declare its virtual viewport size as much wider than its physical display (as it does now), as a max-width media query would depend on that. Does this mean that pages with only simple layouts will have to rely on something other than a change to the default virtual viewport width? And if the complex layouts are going to involve columns for the user to zoom in on, what would their ideal width be?

CSS3 proposes several new units, including 100vw, which is the width of some kind of viewport But which viewport should it describe in the iPhone – the virtual one or the physical one? If it's the virtual one, that presents some options.

A page that uses a complex layout when more space is available could limit the widths of each of its columns to 100vw. A page that only uses a simple layout could apply that limit to its whole self.

However, it seems likely that vw refers to the virtual viewport (i.e., viewport as defined by CSS2.1, and then interpreted by the iPhone's implementation of media queries) The media feature width is defined in terms of a viewport, so the iPhone will likely define 100vw to be 980px. device-width is defined in terms of a rendering surface, and it seems that the iPhone claims that to be 320px wide, but other browsers will equate it to the screen width, so it's not generally useful to us.

Perhaps we need a new unit which relates to the maximum width which a line of text can be without becoming too long to display completely, and without becoming too small to read. 100idw could be that width.

Suppose you wanted to limit the width of a column of text. You could mark it up like this (with a redundant <div> so you can apply two limitations):

<div class="column">
  <div>
    <!-- Column text -->
  </div>
</div>

Given the new unit idw as defined above, you can specify two restrictions on the text, with the smaller applying:

.column { max-width: 35em; }
.column > div { max-width: 100idw; }

An iPhone could declare that 100idw is equivalent to around 320px, which will likely be more constraining than 35em, as required in an iPhone to prevent the lines becoming too long when zooming in sufficiently to read them. (Actually, it could probably go up another hundred pixels without making the text unreadable.)

However, in a regular desktop browser, 100idw could equal the width of the window, probably around 1000px in many cases. That would typically be more than 35em, which would then become the applied limit.

With some other CSS3 features, you could make it adapt to the font size applied to the column:

.column { max-width: 35em; }
.column > div { max-width: calc(100idw * 1em / 1rem); }

You could even do away with the nested <div> altogether:

.column { max-width: calc(min(35em, 100idw * 1em / 1rem)); }

In effect, we are expressing precisely the requirements of two similar goals:

  1. We don't want lines to become so long that the reader has difficulty finding the start of one line having finished reading the previous. In that situation, a width proportional to font size is appropriate, e.g., 35em.

  2. We don't want the lines to become so long that, when zoomed out to fit into the iPhone's screen, the text becomes too small to read. In that situation, a width proportional to the product of the unzoomed display width and the font size is appropriate, e.g., 100idw.

The user-defined max-width solution?

The idw unit might be worthwhile for other reasons, but perhaps there is a simpler solution involving only user stylesheets.

Let's make the following assumptions:

  • The user has no knowledge of the structure of pages in general. If she is going to set max-width in a user stylesheet, her only real option is to set it on <body>.

  • In the iPhone, a user stylesheet sets the following:

    body {
      max-width: 15em; /* or similar */
    }
    
  • The iPhone continues to declare its default viewport width at 980 pixels (or a similarly large value). This means that authors can write media queries that distinguish between narrow, zoomable displays and plainly narrow ones.

  • The author does not assume a default of:

    body {
      max-width: none;
    }
    

    This means that if he wants to use all available space, he must explicitly provide that setting himself.

Now consider what happens in the following scenarios:

  • An author who writes an unstyled page can (correctly) assume that excessively long lines are the visitor's problem, as the 15em limit will apply on the iPhone.

  • An author who wants to set a width limit on his own content, rather than assuming that the user will do it, doesn't set max-width on <body>, but inserts a <div> around all content, and sets it on that:

    body > div {
      max-width: 35em;
    }
    

    On the iPhone, 15em wins again, as the user stylesheet prevents more than that from being offered to the nested <div>. On conventional browsers, 35em will apply, or the user's default if it happens to be smaller.

  • If an author wants to exploit the large virtual space of the iPhone with a columned layout, he first detects that the space is available with a media query, which he can do because the iPhone offers 980 pixels as the width media feature. Then he overrides any user setting of max-width on <body>.

    @media (min-width: 48em) {
      body {
        max-width: none;
      }
    
      #col1 {
        position: absolute;
        /* ... */
      }
    
      #col2 {
        position: absolute;
        /* ... */
      }
    
      #col3 {
        position: absolute;
        /* ... */
      }
    }
    

    On the iPhone, or indeed any browser with a user-specified body { max-width } setting, that setting will be overridden so the full space can be exploited.

The media-feature solution?

None of the previous solutions deal with a case where one avoids stressing a column when it has limited space. For example, a small navigation menu could be floated to the side only when sufficient space is available, by using a min-width-based media query.

But we can't base a media query on width because that needs to be 980px to allow sites to detect when a large space is available. We can't base it on device-width because that is no narrower than width in conventional browsers. We can't write a media query for a particular element representing the column, as that sort of thing leads to recursive computation which CSS engines shouldn't have to deal with.

We need a new media feature related to the idw unit, say, display-width, whose value is always 100idw, but can be compared against widths in other units, such as ems.

/* Play safe, by default. */
ul.nav > li {
  display: inline-block;
}

@media (min-display-width: 20em) {
  /* Float navigation, if space available (100idw ≥ 20em). */
  ul.nav {
    float: left;
  }

  ul.nav > li {
    display: block;
  }
}