In the beginning, there were no smartphones. As cell phones were taking off, you more than likely had a Palm Pilot if you wanted to keep track of calendars and appointments. What web you could get on phones was limited to WAP or some subset of HTML. Phones and PDAs simply couldn't handle what desktop browsers were doing (which, at the time, was mostly animated .GIFs and MIDI background music). As a web designer, you were pretty much required to create a separate website if you wanted a mobile version; most sites didn't bother.
Web design began to mature, and people started using CSS to style their websites. The advantages of CSS were clear — sites could be consistently styled in a way that kept style separate from content. One of the innovative features put into HTML 4 (which, I should remind you, became a W3C recommendation in 1998) was the use of media descriptors to allow browsers to selectively apply certain CSS styles for different media. One of those media types defined in HTML 4 was the 'handheld' type, for portable devices with small screens. With this feature, it was easy to make the same webpage look good on both the big screen and the small screen simply by creating two different stylesheets.
To be fair, the handheld media descriptor has never been implemented very consistently. Opera was always a good supporter, and Mobile IE supported it in a way (by enabling both handheld and screen styles). My last phone's built-in browser supported it beautifully, but a lot of phone browsers didn't.
Fast forward to 2007 — the iPhone comes out and takes the US smartphone market by storm. It packages a slimmed-down version of a desktop browser engine, WebKit, which would become a trend in smartphones. Frustratingly, WebKit on the iPhone paid no attention to the handheld media descriptor, most likely so that the "full web" could be experienced (This is, of course, a ridiculous idea — phones have only just now caught up with resolutions popular on PCs in the early 90's, and even infinite pixel density won't help you read three point text).
The popularity of the iPhone and Apple's intial unwillingness to support native applications on the platform led to a lot of mobile versions of sites that worked merely by detecting the iPhone's version string. Even today, you can find sites that assume any phone with "Mobile" and "WebKit" in the user agent string must be an iPhone, and will render the page at a fixed 320 pixels wide. Suddenly, we've taken a step back. Nowadays, if you want to make a mobile site, you make a completely new site and use user agent sniffing to switch to it. Witness the rise of m.whatever.com. So now we're worse off than we were with WAP, using fragile heuristic approaches and needlessly duplicating effort.
Well, Apple also gave us a useful tool to help sort out this mess. First seen in Mobile Safari, the viewport meta tag allows your webpage to tell the phone how wide its viewport is — which is to say, it changes how wide the phone's viewport pretends to be. It's admittedly a hack, but the upshot is if I say my viewport is 640 pixels wide, the page will be scaled as though it's 640 pixels wide even if it's rendered on a larger or smaller screen. By default, mobile WebKit based browsers tend to report that they're quite a bit larger than they are. My Pixi, for example, pretends that the screen is 960 pixels wide (If you're curious about yours, test here). If you want the page to act as though it is at whatever the native resolution of your screen is, just use "device-width" for your width.
So now that we have a way of un-fucking the browser zoom, how do we get our mobile style in place? Well, I came up with a sneaky solution. I wrote a JavaScript function which iterates over the page's stylesheets (via DOM Level 2 Style) and rewrites the media descriptors to change 'handheld' to 'screen' and 'screen' to 'unknown.' Then I simply detect the viewport width as the page loads, and enable the handheld styles if it's small enough. I currently specify my viewport as 480px wide and enable the handheld mode if the viewport is <= 480px. It's certainly a hack, but it works. And if you want to get fancy, you can remove the server-side user agent detection, put that logic in the javascript, and dump the m. site. Nice, huh?
The code in question is in force_handheld.js, the relevant functions are enableMobile() and disableMobile(). Don't use the whole file, it's designed around my site. For some reason, the technique doesn't work in Firefox. The data is properly mangled, but it seems that after the page is loaded, Gecko ignores any changes to the stylesheets' media descriptors. I'm sure all three Maemo users will be terribly disappointed.
I've already applied this hack to my site, which should make it much more usable on mobile browsers. I'm also using the hack in the case where a desktop browser is too narrow to fit the content column, which I think works a little better than the previous solution.