One line of code

Want to make your site look better on the iPhone with one line of HTML?

It’s easy—just add a <meta> tag that lets the iPhone know how wide to display the initial page. I added the following code to the <head> in my template yesterday:

<meta name="viewport" content="width=808" />

Every browser besides MobileSafari will ignore this information. But it does something very important on the iPhone: it optimizes the viewport for your content.

By default, the iPhone uses a viewport of 980 pixels—a value chosen to maximize compatibility with a broad range of web sites. When you specify the viewport width explicitly, you will eliminate any empty space between that 980 pixels and the width of your <body> element.

On this site the <body> is 808 pixels wide, so there were 172 pixels of content-free space being used to display the page. On a screen that’s 320 pixels wide, that’s significant. So much so, that by making this simple change, the headings on my blog posts are now readable on first load of the page (previously, the text was too small.)

As always, a picture is worth a thousand words. Here are the changes that could be made on a couple of my favorite web sites:

Zeldman

Looking at Jeffrey’s CSS file, I see:

html {
	min-width: 742px;
	}

So his one line of code would be:

<meta name="viewport" content="width=742" />

That’s all folks!

Daring Fireball

Likewise, Gruber had specified this CSS:

body {
	...
	min-width: 760px;
	}

Which would mean this addition to the <head>:

<meta name="viewport" content="width=760" />

But there’s a problem…

MobileSafari uses a heuristic to adjust the viewport based on the width and aspect ratio of the page. And since Gruber is a man of many words, the page is long and the initial scale for the viewport isn’t optimal. So he could use this instead:

<meta name="viewport" content="width=760, initial-scale=0.4" />

But his problems aren’t over yet—there’s still an issue with usability. You can double-tap to zoom in to read an article—and when you double-tap to zoom back out, you’re using the suboptimal scale factor again. This is easy to work around by specifying a minimum scaling factor:

<meta name="viewport" content="width=760, initial-scale=0.4, minimum-scale=0.4" />

And it’s still just one line of code!

Are you wondering how I came up with that magic scaling factor of 0.4? I used a tried and true development practice: trial and error. While using this sophisticated technique, make sure to close the window in MobileSafari (by clicking on the red X icon.) The viewport scale is not modified when you refresh the page, so you’ll only see changes when starting on a new page.

Hopefully, Jeffrey and John will read this post and make the changes to their sites—I like reading them on the iPhone :-)

Update: WordPress is turning the double quotes in the examples above into smart quotes. You’ll want to convert them before adding them to your template. And for more information on viewports, check the Apple iPhone developer page (you must click on “Optimizing for Page Readability” to view it.)

iPhone scrolling tip

If you’re an iPhone owner, you’ve probably encountered a problem with scrolling. For the most part it’s very intuitive, but there are occasions where you can’t get to what you want. The problem is that there aren’t any traditional scroll bars, so it seems like you are stuck. Even very smart engineers who know a lot about mobile computing are having problems.

Here are a couple of situations I’ve encountered:

  • While editing in a text area with a lot of text. You probably have resorted to using the insertion point to (slowly) reposition the text.
  • On a web page has content displayed using the CSS scroll:auto property. You’re stuck looking at the top of a <div> and can’t get to the lower part of the content.

Fortunately there is a very simple, yet unintuitive, solution for both of these situations. Use two fingers to scroll the content.

Flicking doesn’t work, but it’s better than nothing. I certainly wouldn’t design an interface around this “feature” due to its lack of discoverability—just use it as a workaround to deal with existing sites. And considering that people are submitting bug reports about scrolling not working, it looks like Apple has some work left to do with this “scroll within a scroll” gesture.

Credit for finding this trick goes to Matthew Krivanek on the iPhoneWebDev mailing list. I found his post while looking for solutions to the fixed positioning problem in MobileSafari.

Multi-touch on the desktop

Now that the iPhone has given us all a taste of a multi-touch user interface, I have been hearing many people say how cool it would be to have touch-based input on a new line of desktop displays from Apple.

If you’re one of the people who think that a multi-touch monitor is a good idea, try this little experiment: touch the top and bottom of your display repeatedly for five minutes. Unless you’re able to beat the governor of California in an arm wrestling match, you’ll give up well before that time limit. Now can you imagine using an interface like this for an eight hour work day?

One of the things that people don’t realize about the iPhone is that it works at a low angle (as opposed to the high angle of your desktop or laptop display.) Our bodies are more comfortable and adept at handling repetitive physical tasks when they are performed at these low angles. What works well for the eyes does not work well for the hands.

If you’re old enough to remember a time before CAD systems, you’ll likely remember drafting tables. These tables were adjustable from completely flat (a low angle) to somewhere around 40° (a medium angle.) A drafting table is an environment where it is easy to work with your hands and associated tools for hours on end.

The iPhone’s multi-touch UI works similarly: if you watch people use it, I think you’ll see a lot more people working at waist level than at chest level. The only time you need the interface close to your head is when you’re enjoying those 3 pt fonts in MobileSafari :-)

Of course, Apple could come up with some kind of ergonomic multi-touch desk. Or we could all go out and buy a Microsoft Surface real soon now. However, I’m pretty happy with the recent demise of the glass-based CRT and not looking forward to the added weight that a touch based interface would add to a 30″ LCD monitor.

But even if there was a solution to the ergonomic issues, there would be problems mixing mouse-based applications (with small hit areas) with touch-based inputs (and large hit areas). Touch-based UI is not something you just bolt onto existing applications—it’s something that has to be designed in from the start.

You can already see this mismatch between the mouse-based and touch-based environments. All you need to do is view a web application that is targeted at the iPhone browser. In a desktop environment the controls seem large, but on the phone they are comfortably sized.

Resolution independent interfaces may solve some of the problems with control sizes, but the fact remains that a desktop interface has a much higher information density than a mobile one. A desktop is a multi-tasking environment while a mobile device is typically oriented towards a single task (making a call, finding a restaurant, getting directions, etc.) Don’t assume that the multi-touch you are using in a single task environment, with its lower information density and more focused interface, will be equally successful in a high density, multi-tasking desktop. Take another look at Jeff Han’s amazing demo and realize that he’s only working in one application at a time—what happens when you add a browser, an e-mail client, and some of your other favorite applications to that desktop?

I also find it difficult to believe that any kind of touch-based UI will replace the keyboard anytime soon. For people who are touch typists, you can’t beat the feedback of a key press for common applications like word processing and e-mail. Eventually we’ll have haptic interfaces with simulated feedback which will obviate the need for a separate keyboard.

The bottom line is that we’ve only just begun a journey that will fundamentally change the way we interact with machines. A major part of this change will be evaluating new and better ways to use computers—what has worked well in the past may not work so well in the future. And because of the magnitude of this change, I think there will be an extended period where touch-based, mouse-based and keyboard-based interfaces will need to coexist. If we’re not careful about developing these new interfaces, we’ll end up with something like Victor Frankenstein’s creation: pieced together and frightening.

Update: Tog agrees with me. Make sure to check out the Starfire video for ideas on how horizontal and vertical work surfaces can be integrated. Even though the cultural and technological elements are a bit dated, the human-centered design is still relevant.

Quartz and Javascript, sitting in a tree…

Even if everything isn’t copacetic in the land of “sweet”, at least Javascript and Quartz are getting along.

Thanks to Apple’s contribution to the WHATWG’s HTML 5 specification, it’s pretty easy to use Quartz graphics technology in an iPhone application. Together with MobileSafari’s event handling, you can start to do some fairly sophisticated drawing using a <canvas> element on the iPhone.

Here’s a sample application that draws and updates a graphic based on user input: canvas_test.html

(Make sure to resize your browser to have a 360 pixel height if you’re running on a desktop instead of the iPhone. And don’t be a fool: view the source.)

A few things to note:

  • The Javascript timer events only fire if the page is frontmost in Safari. Don’t make assumptions about when stuff will happen based upon your previous AJAX experience.
  • The minimum interval for the timer is much higher on the iPhone than a typical desktop browser. Change the setTimeout() parameter from 1000 to 10 milliseconds, and you’ll see that it’s not fast enough for serious gaming. You might also want to look at CPU usage on the desktop as a clue to why the iPhone developers chose to limit the timer interval.
  • It appears that MobileSafari isn’t very fast at recognizing mouse (multi-touch) events. Try pressing the screen quickly in different locations: you’ll see that many of the events are not captured.
  • I’ve said it before, and I’ll say it again. The finger is a very imprecise pointing instrument. Try to get the graphic centered at 100, 100 and you’ll see what I mean.

And if you had any doubts about the WHATWG being a good idea: this example works just fine in Firefox, Camino and Opera. I’ll let you guess how well it works in Internet Explorer…

Update: I built a graphing calculator using the concepts presented in this essay. Try launching the application on your desktop and iPhone: there’s quite a performance difference between the two environments. To understand the differences, I ran some benchmarks.

Bittersweet

Take a look at every application on the iPhone: what do they have in common?

The answer is a navigation bar at the top and a toolbar at the bottom. The navigation bar at the top gives the user a well known location for “backing up”, starting an editing session, and canceling operations. The toolbar provides a way to switch modes, change views or other operations with the dataset at hand.

Both of these key interface elements, navigation and tools, are in fixed locations on the iPhone screen. If you’re trying to develop a “sweet” web application for this device, you’ll quickly find that you can’t follow these standard conventions. That’s because there is no fixed positioning in Safari for the iPhone. Bittersweet, indeed.

The position of the navigation and toolbar items is very important since they allow the interface designer to avoid the “finger shadow“. When you are navigating, your finger can obscure content since it’s going to change anyway. Locating a toolbar at the bottom of the screen allows you to work with data without the risk of hiding it.

Some might argue that there’s no way to have fixed positioning on the iPhone since it’s based on view ports rather than scrolling. But this argument is quickly dismissed when you consider the <meta name=”viewport”> configuration supported by Safari on the iPhone:

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

This allows you to specify the exact size of the viewport your web application is using. It can also prevent or limit the scaling of the viewport, so you’re guaranteed to be working in a consistent coordinate system. Most iPhone web applications I have looked at are optimized using this feature.

The lack of fixed positioning in the browser also makes it clear that everything else on the iPhone is not a web app because the elements at the top and bottom of the screen don’t move. So much for Apple eating their own dog food. Instead, we end up with a dog shit sandwich.

(Note: These applications may well be using WebKit within Cocoa views to facilitate the rendering of content, but the layout of the views on screen is not done with HTML.)

So let’s look at how this affects usability. As an example, I’ll take a look at PocketTweets—a recently released web client for Twitter. A beautiful application that’s marred by the limitation mentioned above.

When viewing a page of tweets (posts) you will quickly find yourself scrolling like crazy on your iPhone. Switching a view requires that you scroll to the bottom of a long page, often causing Safari to render portions of the page just so you can get to the buttons. Obviously, these important buttons should be located in a fixed <div>.

This limitation with fixed elements also affects the amazing work done by Joe Hewitt. Take a look at the example code on the iPhone and you’ll notice that the navigation bar scrolls off the screen when there are more than nine items in the list (e.g. the song titles.) A fixed element would solve this problem.

For those readers who don’t yet have an iPhone, here’s an example that demonstrates how the fixed element should work, and how it’s broken on the iPhone: not_fixed.html When you are testing in Safari 3, you’ll need to resize the window so that the content area is 360 pixels high. When you switch to “absolute mode” you’ll have the same experience as on the iPhone.

Finally, it’s interesting to note that this bug implies that Safari on the iPhone uses a different rendering engine than Safari 3. There’s nothing else like it, even Safari 2. Obviously, this is a disappointment for Mac and Windows developers who were hoping to use a desktop browser as a proxy for iPhone development.

If you have an ADC account, I’d suggest that you submit a bug report so that the iPhone team realizes the importance of this bug. Please reference Bug ID# 5325294.

Postscript: While writing this essay, it became quite cumbersome to use “Safari on the iPhone”. Next time, I’ll use iSafari” even though it’s not very descriptiveMobileSafari“.

Update: Apple reports that this is a known issue, please refer to Bug ID# 5327029.