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.