The Ten Commandments of Web Design: Commandment Two

View blog reactions Written on April 4, 2007 by Chris Heald

Broken LinkI’m back with another entry in my series on web design. If you missed it, here is part one.

Most every professional web site out there employees Javascript to some degree. With AJAX catching on as it is, Javascript is becoming more and more popular. Unfortunately, this means that more and more sites are breaking one of the fundamental rules of web design.

The Second Commandment: Thou shalt not navigate with Javascript alone

Currently, according to W3Schools, approximately 6% of all browsers either do not have Javascript, or have it disabled. This drops by approximately 2% every year, but right now, that number is significant enough that you cannot ignore it in a professional product.

6% means that 1 of every 17 users will not have Javascript turned on. Do you want your site to be inaccessable to those people? Of course not.

Additionally, abuse of Javascript for navigation can lock out what is arguably the dominant browsing pattern on the web these days: tabbed browsing. Opening a new tab via middle-click or ctrl-click does not execute the “onclick” code. It will always execute the “href” in a new tab. Without the context of the existing page, nothing happens, limiting your users to single-tab browsing. Ouch!

Before I really get into this, let me preface the rest of this article by saying that there are some products that simply don’t work without Javascript, period, paragraph. That’s fine. If javascript is a core technology to your product, and it’s assumed that if you don’t have it then you can’t use any part of the product, then this doesn’t apply to you. This article isn’t about those products; this article is for those products who don’t rely on Javascript as a central technology, but who have some features that won’t work without it. If you do have one of those sites, then you should take the example of YouTube and WoWHead who alert the user that Javascript is not enabled, and guide them in enabling it.

This will, however, be extremely applicable to ASP.NET and Cold Fusion users, as both frameworks abuse the “link postback” and assume that all users have Javascript enabled.

Let’s take for example one of the most popular sites on the internet: Myspace. On their Browse Users page, they have a search form. This search form has two tabs, “Basic” and “Advanced”.

They have code that looks something like this:

<a href="javascript:__doPostBack('ctl00$Main$ctl00$basicView','')" class="active" id="ctl00_Main_ctl00_basicView">Basic</a>

This works really well…when the user has Javascript. It switches the user to the advanced or basic view (via a full page reload, I might add - completely unnecessary since they’re already using Javascript), and presumably uses the postback to preserve any search options that the user had selected but had not searched for.

What happens when the user doesn’t have Javascript? Absolutely nothing. The link is there, changes to a hand on mouseover, and does nothing when clicked. Oops.

When 1 in 17 MySpace users can’t access the advanced search form, we have a problem! So, how do we fix this?

First off, abandon the idea of using the “javascript: …” HREF target. Never do it. Ever. There is absolutely no need to do it. It isn’t semantic, it doesn’t work with Javascriptless browsers, and even more importantly, users can’t copy-and-paste it to their friends.

Instead, use the onclick handler and return false from it. Then, set your href= to a Javascriptless fallback URL. What this does is it sets up a chain of actions. When the link is clicked, the onclick handler gets executed if Javascript is enabled. We can do our postback, or AJAX call, or whatever, and then return false. The return short-circuits the process and prevents the browser from following the HREF target. If Javascript isn’t enabled, the obviously, we can’t execute the onclick handler, so it just navigates to the HREF target. Copying the link or opening it in a new tab will likewise invoke the HREF target, allowing us to use those operations seamlessly.

So, let’s look at our MySpace link when it’s fixed.

<a   href="/search.cfm?mode=basic"
    onclick="javascript:__doPostBack('ctl00$Main$ctl00$basicView',''); return false;" 
    class="active" 
    id="ctl00_Main_ctl00_basicView">Basic</a>

It’s more code - that’s undeniable, but we’ve picked up some very important functionality.

  1. It works regardless of Javascript status. You’re never going to have users that can’t access it because they don’t have Javascript, or have it turned off.
  2. Users can see exactly what’s going to happen when they click that link. When you put your mouse over a link and it says “javascript:__doPostBack(’ctl00$Main$ctl00$basicView’,”)”, that means exactly Jack Squat to anyone that hasn’t spent time developing Myspace’s website. When a user can see “This link goes to search.cfm?mode=basic”, they can guess what’s going to happen easily enough.
  3. Users can right-click it, copy the link, and paste it to their friends. This isn’t a big deal for things like the Basic versus Advanced search form, but what if you have some page or content that you want people to share around? If they can’t share it with their friends, then they can’t virally market your product for you, and you lose business.
  4. Last, but very certainly not least, these links are now compatible with tabbed browsers.

The only reason to NOT provide a Javascript fallback is laziness, and lazy developers lose customers.

The same applies to AJAX links and forms. Take for example this hypothetical example: you have a paged list view. You have 100 items in a list, and want to view 10 items per page. AJAX makes a nice application for this, because by AJAXifying the links, you can update the list in-place inside the page rather than having to make the user do a full page navigation and reload multiple KB of content that they don’t need to reload.

Let’s assume you have page links like so:

<a href="#" onclick="doAjaxUpdate('/page/2', 'displayList'); return false;">Page 2</a>
<a href="#" onclick="doAjaxUpdate('/page/3', 'displayList'); return false;">Page 3</a>
<a href="#" onclick="doAjaxUpdate('/page/4', 'displayList'); return false;">Page 4</a>

This lets the user click the links to update some div with the ID of “displayList” with the contents of the “/page/#” URL. Good stuff, no? The user spends less time waiting for the page to load and you save bandwidth. Win-win all around.

But what happens if I have Javascript turned off? All of a sudden, I can only see items 1-10. I can’t see items 11-100. This is pretty bad for selling products or for building a loyal userbase. We can fix this with something like the following:

<a href="/page/2" onclick="doAjaxUpdate('/page/2', 'displayList'); return false;">Page 2</a>
<a href="/page/2" onclick="doAjaxUpdate('/page/3', 'displayList'); return false;">Page 3</a>
<a href="/page/2" onclick="doAjaxUpdate('/page/4', 'displayList'); return false;">Page 4</a>

It is more code, again, but it provides us with the same benefits as before. Semantically valid links, sharable links, tabbed-browsing-friendly links, and links that work in Javascriptless browsers.

That little extra bit of effort on your end will enhance the experience for all your users, whether they be tabbed browser users, or users without Javascript enabled, or just users who want to share links with their friends.

As an off-topic plug, every web developer that uses Firefox should be using Firebug. It makes debugging HTML, Javascript, CSS, and AJAX absolutely painless, and is an absolutely invaluable tool. Don’t leave home without it.

« Back to Part 1 | Part 3 coming soon!

Leave a Reply

You may use these HTML tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>