Thursday, November 15th, 2007

Unobtrusive JavaScript – Rules to work by

Category: Accessibility, JavaScript, Unobtrusive JS

From what I’ve seen, it appears that many developers, especially those new to the JS space are somewhat confused by the reasons for developing JS in an unobtrusive fashion. Typical arguments that I’ve heard are:

  • It takes too long to develop
  • If they don’t have JavasScript, then they’re out of luck
  • We shouldn’t have to code for the 5% that don’t want to use an up-to-date browser

I’m sure many of you have heard similar comments and had many debates over the semantics of this topic.

Which leads me to a new blog post that tackles unobtruse JS and provides excellent feedback into the subject. Christian Heilmann continues his advocacy of writing JavaScript in unobtrusive ways in his most recent blog posting, The seven rules of Unobtrusive JavaScript.

Christian’s posting not only provides the reasons why it’s important but also includes example code that drives the idea home. Right off the bat, he makes several points that really make sense:

Probably the most important feature of unobtrusive JavaScript is that you stop making assumptions:

  • You don’t expect JavaScript to be available but make it a nice-to-have rather than a dependency
  • You don’t expect browsers to support certain methods and have the correct properties but you test for them before you access them
  • You don’t expect the correct HTML to be at your disposal, but check for it and do nothing when it is not available
  • You keep your functionality independent of input device
  • You expect other scripts to try to interfere with your functionality and keep the scope of your scripts as secure as possible.

I conducted a brief interview with Christian via email and here’s what he had to say:

What are the biggest challenges, in terms of unobtrusive JS, that you’re seeing in your work? Are you limited in what you can provide to
your audience?

The biggest challenges are that JavaScript is still considered a thing to bolt on or something that comes from a library/framework. Hardly anyone really plans interfaces in two states: one without scripting and one with scripting. A lot of frameworks tell implementers that they do the checking automatically for them, but in reality this is hardly ever the case. Of course you can say you limit yourself to a less interesting interface when you build it unobtrusively, but you also build interfaces that work for everyone. Just because we can totally change the way browsers interact with users with JavaScript that does not necessarily mean we should. Ajax and JavaScript enhanced interfaces should be planned out by developers and user interface designers / IA / Usability / Accessibility experts. As it is a “brave new world” thing this doesn’t happen a lot, instead we believe in truisms (this is how drag and drop works, believe us).

Has awareness grown? Do you see more developers actually understanding how to write unobtrusive JS and using it in practice?

Yes it has, the hits I get on the article and especially this new one show that. However whenever you talk about JavaScript, there are a lot of “experts” who love to bring their own agenda in. It is good though to see other people than me stating why things make sense. The thread on reddit is pretty cool in that way.

With so many libraries out there at the moment, it’s natural for beginners to look for some help by using them. Has this impacted, negatively or positively, the application of unobtrusive JS techniques?

Neither nor I’d say. It depends on the library. I’ve been adamant to change some of the examples that come with the YUI to be unobtrusive, and I am in contact with other library developers to do the same. Whenever I’ve covered the topic of libraries in my books I also made sure the examples show how you can do things unobtrusively. It is a bit of a shame that a lot of libraries don’t wear that idea on their sleeves though, this is something I’d love to see. The release that made me the happiest was Dan Webb’s unobtrusive plugin for Ruby on Rails: It is up to people to start advertising the unobtrusive use of libraries more. I am currently doing that with an article series on, and every publisher I am in contact with is crying out for books about using libraries. So if you are inclined to write, this is the time.

You can read more about Christian’s views on unobtrusive JavaScript at his blog post: The seven rules of Unobtrusive JavaScript

Posted by Rey Bango at 8:46 am

3.8 rating from 46 votes


Comments feed TrackBack URI

– It takes too long to develop
IMHO its the only real argument against Unobtrusive JS and degradable ajax

You can take at least the double on a time estimate for adding one feature to an existing project the ajax way, and finding customers willing to pay twice for that sort of enhancement (invisible at their eyes) is really really hard.
They rather prefer invest in new functionnality.

Of course coding degrabable can not be so long at all, and can be required for referencing dynamics contents.

But unobtrusive, I mean testing for the browser’s JS native support to use equivalent methods for your code to support IE 5.5 or Netscape is unoubdably a huge cost for 2% people using such old browsers. We can also deem these peoples doesn’t use 2.0 sites but use their computer as a fax machine with emails.

Imagine you’re working in a windows programming, supporting different version of the OS is also a huge cost, coding for all browsers is the same at my eyes. You can argue Yahoo, Google, or big open source projects have the ressources to do this, well, when you’re alone and have only few days to implement new functionnality being unobtrusive is the last thing about which you care.

Comment by BBB — November 15, 2007

BBB, how about using libraries that do that for you? Most are available as open source. Also, it is not that hard to put that in an init() function and be happy ever after.

Comment by Chris Heilmann — November 15, 2007

way to go! a can only agree on chris.

Providing js this way might be harder at the beginning, since you´ll probably have to learn js (if you are using rails:-) ), but afterwards it empowers you to to do things like
– switching a js implementation for a special browser(iphone)
– better debugging and profiling
– server site testing in automated deployment environments
– porting whole js chunks into another site or software(air application)

Comment by MP:Schorsch — November 15, 2007

why NOT to do unobstrusive js:

1) more scenarios to test
2) target audience is lame (if on a browser that doesn’t support js they are either on a REALLY old machine or are paranoid types, either way they probably won’t spend any money on your product)
3) slows down dev
4) adds complexity

Comment by phil swenson — November 15, 2007

1. hey great your softwares becomes better!
2. target audiences like big companies (== big money), have disabled javascript for good reasons!
3. can also speed it up if you are using the right libraries.
4. inline javascript, like generated by a lot of “hey do easy ajax with me”-libraries adds the same complexity to you code as you would with inline css. Or to bring another example what if your rails ajax helper has bugs? how do you find out where the bug comes from? from js, ruby, rails, the browser, your code ..

i could go on for miles and had this kind of discussion more than one time the last couple of month…

Comment by MP:Schorsch — November 15, 2007

1. hey great your softwares becomes better!
— Becomes invisibly better… no one pays for invisible. Doubling your design scenarios and possibilities is costly.
2. target audiences like big companies (== big money), have disabled javascript for good reasons!
— What good reasons? XSS? Big corporations would stand to gain the most from Axaj-y interactions on intranets and such as they wont notice bandwidth hits as bad.

4. inline javascript, like generated by a lot of “hey do easy ajax with me”-libraries adds the same complexity to you code as you would with inline css. Or to bring another example what if your rails ajax helper has bugs? how do you find out where the bug comes from? from js, ruby, rails, the browser, your code ..
— Nothing says this is a return to in-line JS, just the simplicity of designing a js only interface.
Basically, I look at it this way… do we design separate interfaces for those with CSS turned off?

Comment by Jon Hartmann — November 15, 2007

When are we going to start treating javascript as a REAL language to get REAL work done … instead of something to make things cute and bouncy? One of the main advantages with javascript is that you push certain tasks to the CLIENT side of the equation from the SERVER side of the equation. Unobstrusive javascript is self-defeating in nature … and it costs you more $$$ not only in development, but in performing tasks which would otherwise be done on the client side.

Comment by Marat Denenberg — November 15, 2007

Unobtrusive JS is a good thing, but few of its advocates remember that sometimes we’re building a web app for a specific task, targeted at specific users, who will gladly enable JS (and even use a modern browser, not IE 5.0 or similar) to access the service, because this makes their own work more convenient. Our company is running a commercial service that allows building surveys online with an interactive editor. Obviously, possibilities for js/ajax in the interface are endless, and in a new version of the service we require JS and A-grade browser to run. Why? Because without JS/AJAX, the experience would be painful for the user to work with, and 2x more expensive for us to develop. We have online editors for complex objects that could require 5 or more page reloads to add a single item if JS is not available. Also, we don’t support IE5, since it breaks some of our key features, and almost every computer that runs IE 5 can run Firefox or Opera as well.

It is not a good idea to make people switch browsers to view a simple web site; it still may be a good idea to make them switch browsers to use a specific web app.

Comment by Max Shirshin — November 15, 2007

Beyond accessibility that such approaches provide it should be noted that well thought out JavaScript that addresses multiple conditions also has the distinct advantage of generally being more secure as well. When you address edge cases of bad data, bad browser, script off, etc. you tend to plug the common holes that people exploit.

Comment by Thomas Powell — November 15, 2007

We kind of do make alternative layouts for people without css.. doing things like putting the main nav on the bottom of the page to bring content to the top, etc..

And for js, just don’t use inline events. Right? That’s easy enough.

Comment by Jack — November 15, 2007

I’ve been mulling over the “unobtrusive or not” argument in my head for a little while and I’m still not decided either way. I have a hunch though that it’s going to be a “don’t become hammer-nail on this” in nature and that for some projects it will be the right thing to do and for others it won’t.

My main gotcha against 100% unobtrusive JS is collaboration. If you have many people working on the javascript portion of a project, it’s really easy to see what everybody has been doing with an element by checking out it’s handlers in the markup. It seems as if it would be more difficult to divine which events are being watched for an element by sifting through all the javascript every time you had a question.

On the other hand, we’ve been very happy with how our layouts degrade absent CSS and I really do believe that a separation of scripts and markup can be a beautiful thing. Especially if you’re dividing the labor between scripters and css/markup specialists.

Currently we’re mixing the two in a project. For things with global scope (window, body events, nav stuff, init) we’re unobrusive but for element specific functionality we’re putting the handlers in the markup. This is because we have people working on different parts of the markup. If you have to do something with an event that happens on every page, you can’t just do an S/R stomp on everybody. And if it’s element specific, the owner of that element can add it themselves and not stomp on the people working on global init functions. Yes, source control is supposed to manage this for you, but source control can’t manage the context in developers’ minds. So this hybrid has evolved. I don’t know if I like it, but it is what it is.

Comment by tack — November 15, 2007

phil swenson writes: “target audience is lame (if on a browser that doesn’t support js they are either on a REALLY old machine or are paranoid types, either way they probably won’t spend any money on your product)”.

No, there are other possibilities beyond your binary interpretation, such as managers and employees with fat wallets surfing around on corporate or public sector networks filled with legacy machines administered by paranoid types. Also, people with disabilities often have to disable JS because most JS-based interfaces in the wild are less accessible than the JS-less alternative. This is for various reasons, predominately developer incompetence (e.g. creating user interfaces that are dependent on mouse events) but also because of shortfalls in current assistive technologies or user agents that neither end-users nor web developers can easily hack around.

The target audience (surfers with JS disabled) is thought to be roundabouts 5-10% of users, roughly more users than Safari, IE5, and Opera combined. Competitors who cater to them look forward to taking the 1 in 20 users you turn away at the door. And that’s just the humans. If your site is content-driven, since search engines continue to favour content available without scripting, competitors can also look forward to getting many visitors before they even reach your site.

Jon Hartmann writes: “do we design separate interfaces for those with CSS turned off?”

CSS is designed to enable content to be separated from presentation, with the content going into the HTML and various suggested presentations going into the CSS. If you use these technologies correctly, then your HTML automatically provides the “interface for those with CSS turned off”.

Marat Denenberg writes: “Unobstrusive javascript is self-defeating in nature … and it costs you more $$$ not only in development, but in performing tasks which would otherwise be done on the client side.”

If you are not depending on JS (the only bit of “unobtrusive” you’re considering here) then every task that you need to push to the client side can still pushed to the client side, except for the users with JS disabled or particular functionality unsupported. If you did depend on JS those additional tasks would not be done clientside – on the contrary, they would simply not be done, full stop.

Comment by Benjamin Hawkes-Lewis — November 15, 2007

yeah come on ajaxians… the only thing more old school than surfing around on some po-dunk browser is choosing to build a website that won’t run for anyone that’s not as fancy pants as yourself. We’re supposed to be at the forefront of this client side revolution.. don’t squander the power and ruin it for everyone.. remember the blink tag?

Comment by Jack — November 15, 2007

^^ oh and just so ya know, i’m Jack Gordon.. not Jack Slocum.. that guy rocks.. I’m just a noob

Comment by Jack Gordon — November 15, 2007

Not only do I remember the blink tag, I know how to implement it in browsers that don’t support it ;)

Comment by tack — November 15, 2007

Unobtrusive JS (graceful enhancement) is quite simple. Security should be performed on server side (always, imho) so You need input checks there, not “in browser” (just less wrong requestes on server side, never trust only on client side controls) … but You should help users to compile correctly one or more form that were available since Web 0.1 alpha era.
However You can always add more functionalities, FX, Ajax or whatever You need on client side because if server side is “well thought” it will simply send to client just what it asked for and not entire page each request (probably a stupid example: xhr.setRequestHeader(“Ajax-Call”, “true”); … and a better server side response/business/secure logic). That’s just my humil opinion and this is a really interesting post, comments too :-)

Comment by Andrea Giammarchi — November 15, 2007

How about the dev/designer relationship. With obtrusive javascript, imagine how many bastardizations of img onload=”flashReplace(swfURL, this)” you’d find across a big site.

Let’s see:
this.replaceSWF(flashURL); etc …

It’s the same problem flash used to have when actionscript was embedded in each keyframe or within each object. Imagine troubleshooting that bouncing red ball with the “deep-sea sonar” sound effect on the 58th layer of frame 102 because the gotoandstop() got pushed back a frame. Yikes.

Comment by Brad — November 15, 2007

Maybe I could be misunderstood (I know) and I’m sorry for that.
So much developers have to run against time and most of them have “bosses” telling them how, when and why to move.
Most of the time the “bosses” have no idea of the final product, of the programming development and the topic itself. They’re bosses and they do their job: order.
I can understand, maybe, but there’s still the other side of the moon: laziness.
Unobtrusive Javascript is hard to learn, but once you got in your hand the “starter kit” you can run speedly.
You can reuse the code more easily, the pages are cleaner and they work even if javascript is disabled.
Recently I visited the website of a very famous Antivirus company: all the links has the href attribute setted with the infamous “javascript:” link. With javascript disabled I cannot navigate. Greetings to those webmasters!

Comment by H5N1 — November 15, 2007

Benjamin Hawkes-Lewis: “CSS is designed to enable content to be separated from presentation, with the content going into the HTML and various suggested presentations going into the CSS. If you use these technologies correctly, then your HTML automatically provides the “interface for those with CSS turned off”.”

While I agree with you that CSS-less HTML should still be fine, I’d bet that most modern layouts loose a bit in organization/understandability when reordered to their basic HTML layouts. Moving on though, perhaps this was a poor example, as CSS is very different from JS. Expecting your HTML to degrade gracefully without CSS isn’t a big deal, because there is very little that is dynamic about CSS. Other then the :after/:before group of attributes, CSS can’t really inject content, and unless you get into using JS, you really can’t do anything more then some :hover shenanigans to hide and display content. The content might be moved around, made invisible, or shrunk to oblivion, but it is still there.
JS on the other hand is often creating new things wholesale, not just adding ornaments to the DOM tree, but actually manipulating it and changing it. Thats way to much to expect to degrade smoothly. Unobtrusive principles are what to use if you are adding splashes of JS to sites so that they remain accessible. Pop-up menus, date pickers, and form validations and the like, but there simply isn’t much of a way to make a full blow web application degrade gracefully without doing what Google did with Gmail: make a separate application that performs similar functions.

Comment by Jon Hartmann — November 15, 2007

The article should be called “defensive programming” instead of “unobtrusive javascript”. Defensive programming are techniques that allow code to be more resilient to a changes, such as making fewer assumptions and having fewer dependencies. Unobtrusive javascript, on the other hand, can employ defensive programming techniques, but is more of an ideological issue in that the goal is to separate logic from content and not resilience. The reason why the title doesn’t fit is because point 3 is entirely a resilience issue and doesn’t make things less obtrusive.

Comment by Jordan — November 15, 2007

Unobtrusive JavaScript makes sense to enhance a page that is out there on the general unauthenticated web. These pages are usually not as fancy as the pages behind logins.

When the client-side app is heavily scripted, like GMail, the scripted verses non-scripted versions of the site are so different that combining them using unobtrusive JavaScript would be a nightmare. GMail has two separate versions. At login, a gateway script tests the client’s abilities and directs the user to the appropriate version. The non-script version of the site doesn’t need to have all the features. Just the essentials is likely enough to satisfy the smaller market share with JavaScript disabled.

Comment by Peter Michaux — November 16, 2007

I wish I understood why so many developers are divided on this subject. Why would you fight against having a link that goes to ‘delete.cfm?id=123’, which then uses a click event to load in the ajax equivalent instead, and use # instead as the link? You still have to write the server code to handle the delete, why not just let the delete link go to an actual function and hijack it onload? Things like pagination lend themselves perfectly towards unobtrusive effects like “lazy loading” because you still have to write the paging code either way. Just put the ‘next 20’ link at the bottom of a scrolling div, and attach a scroll event that triggers when the link becomes visible. Because it’s a real link the content becomes simple to retrieve via AJAX, and you get the added benefit of having a link that can not only be accessed from alternate browsers but also from search engines as well.

Comment by Mike Ritchie — November 16, 2007

Gmail was a masterpiece of design and marketing that really pushed up the bar for web apps. But I don’t think it’s sensible to idolize Gmail as a paragon of front-end web development, since the Gmail team sometimes fail to use front-end technologies to their full potential, getting simple things cluelessly wrong. A good example is that they often didn’t use the label element to associate form fields with their text labels, rendering much of the basic view less than accessible. So just because the Gmail team didn’t build Gmail with unobtrusive JS doesn’t mean it couldn’t be done. But more to the point: the basic and JS-heavy Gmail views look very similar in functionality to me. What JS-heavy Gmail feature do Jon or Peter specifically think could not reasonably be layered on top of a correctly coded basic view and actually requires the creation of a completely separate application?

Comment by Benjamin Hawkes-Lewis — November 16, 2007

Good post.
One point of contention:
“You don’t expect the correct HTML to be at your disposal, but check for it and do nothing when it is not available.”
The app shouldn’t do nothing, the app should report this problem to logs, either as an error or as a warning. That way users who care will understand why something isn’t working.
Stop dropping errors on the floor! (I’m looking at you, YUI.)

Comment by Travis Wilson — November 16, 2007

I used the Gmail application as an example of a place that serves up two different versions without trying to use an “unobtrusive” method. Gmail, in itself doesn’t do much that a non-JS email client can’t do, but its not really that complex of a web application either, in terms of the user experience. Something like a Ext JS web desktop though, is something different. Heck, more then 50% of that type of interface is difficult to reproduce without JS, or more correctly, they are harder to then “layer” JS on top to turn it into an Ajax application.

Comment by Jon Hartmann — November 16, 2007

It’s interesting this article asks the question “Is awareness of unobtrusive javascript becoming greater”. I’d argue the other way round.

Initially, it was more or less widespread knowledge that Javascript shoudl only be used unobtrusively – ie that if javascript wasn’t turned on, the user could still use all functionality within the website. It wasnt until the new wave of AJAX fans and young whipper snappers that websites started to become MOSTLY javascript based etc.

So I’d say, without any doubt, that with the rise of AJAX, has come the fall of importance of unobtrusive js.

It seems to me that the ‘big tech thing’ before AJAX was semantic web, accessibility, etc. Then there was a bit of a SPLIT – those who still felt strongly about accessibility, and the new wave who were ajax-hungry. The Ajax people decided to just ignore that whole “completely unaccessible” factor, which brings us to where we are now.

Comment by Gavin — November 16, 2007

I don’t get it, why makes it so hard on you guys to build a web page without any JS then, add a JS lib. (which you would work really quickly with after getting used to it) and make everything more “interactive”?

Also, FF and Firebug make it a lot easier to program JS, I personally used to hate it just for the reasons above but it’s much easier after I’ve changed my ways a little…

Comment by Web Design NY — November 17, 2007

currently working on a fairly complex project that is supposed to work offline (on a CD-ROM – i.e. a pure Javascript solution), and work online as well, I finally realized why I hear so many developers complain about the amount of extra work to put into unobstrusive projects: If you build something first that totally relies on JS, then later decide you want to have it work without Javascript, too, then you’ll end up doing the same work again with the server-side scripting language of your choice PLUS the work on how to put these two together. For “normal” web projects, i.e. regular websites I usually do it the other way around: build an application first that doesn’t require Javascript and then put the extra stuff on top. That’s usually quite efficient, as you don’t duplicate functionalities.

Comment by Bernd Matzner — November 18, 2007

ujs4rails is deprecated.

Instead we must use thelowpro extension to Prototype.

It was a bit of a paradox to use helpers in rhtml files that generate JavaScript but in a unobstrusive way.

So now that we are there, Prototype or jQuery? We have now the choice.

Comment by philipperathe — December 13, 2007

Leave a comment

You must be logged in to post a comment.