bender.js - there's no excuse for sidebars on my phone (anymore)

I’m tired of seeing sidebars on my phone. It’s great that my phone can handle every page on the web, and I can muddle through, but it’s been four years since the iPhone killed the “mobile web” distinction and it’s time for web design to catch up. I can’t do anything about ugly design, but I can at least make it dead simple to show your mobile users a different ugly stylesheet.

There are a lot of proposed solutions out there. What I’m looking for in a good solution is:

I’m looking for a solution for informational websites, where a user doesn’t start at the login page, might want to bookmark or share the link, and might or might not visit other pages. That is, it’s a solution for the original web, the world of hypertext and pagerank. These are pages where you can talk about presentation separate from the content. There are a couple of solutions that are almost but not quite exactly what I’m looking for.

Wikipedia has a fantastic mobile site. Only the first section of an article is shown until you click on a section. They detect and redirect, but include “view this page on regular Wikipedia” link in the footer. The biggest downside of this is that the URL changes. If someone shares a link from a mobile device, they will send you to the mobile wikipedia. Unfortunately, the link “permanently disable mobile site” doesn’t do what it says – it only disables redirection from regular wikipedia to mobile. If the fixed the link-sharing problem, I’d call this a perfect user-experience, but requires smarts on the server side.

The solution recommended by A List Apart, is a set of techniques for applying the right styles based on the “media” attribute and using CSS 3 media queries for devices that prefer the stylesheet for “screen”. The problem with this solution is that people think because it’s “standards compliant”, then they won’t guess wrong or have any need for the user to want to switch. The details of these solutions quickly betray any claim to standards compliance. Once you are attempting to detect an iPhone using a combination of device width and pixel density, you aren’t writing to the standards, you’re attempting browser detection, which means in the best case you have to decide whether a Dell Streak 5 is a phone or a tablet, and in the more troublesome case, you break horribly on any new device you haven’t anticipated. With CSS, unlike Wikipedia’s redirect or client-side Javascript, you can’t correct an incorrect default.

There other solutions out there for highly interactive sites like a banks, ecommerce, or webmail. These kinds of sites are not hurt by doing a redirect at the login page and may benefit from having a completely different structure. But this isn’t what I’m looking for.

Since I couldn’t find it, I wrote my own. Bender.js is a small Javascript library to simplify switching stylesheets. You need to create separate stylesheets (“screen.css” and “mobile.css” for this example), add the links somwhere in your header or footer, and then bender does the rest.

<link rel="stylesheet" type="text/css" href="screen.css" id="style"/>
<script type="text/javascript" src="/bender-min-0.1.js"></script>
<script type="text/javascript">
  $(bender("style").add("screen", "screen.css")
    .add("mobile", "mobile.css", "auto-mobile").install());
</script>
...
<a id="mobile" href="#">Mobile Site</a><a id="screen" href="#">Full Site</a>

Before the page is loaded, bender will check for a cookie if the user has manually selected a stylesheet, if there’s no cookie, and a stylesheet is set as “auto-mobile”, then it will check for a mobile browser. If a cookie is set, or if it detected a mobile browser, it swaps out the stylesheet before the page loads. Once the page loads, the user can choose the other style. (This might be confusing if you are trying to read the code. Note that install() does the initial stylesheet change, and then returns a callback to run on page load.)

If you want more detail, check it out on github or this interactive example. You can also download the minified bender-min-0.1.js. You’ll also need jQuery. I’d love to see what people can do when there’s no need to compromise on one style for all users.