Writing Humble Javascript

Saturday, December 30, 2006

Humble Javascript is the ideal I subscribe to when developing Javascript. I define an ideal as a benchmark by which you measure your decisions and actions. It's not a set of hard rules and frankly it's almost always unreachable, but in attempting to get as close as possible you often produce a good outcome. Humble Javascript follows the ideal of Unobtrusive Javascript but is not the same. There are many ways to write Unobtrusive Javascript . Humble Javascript is all about respect - respecting what Javascript does best as well as respecting XHTML and CSS.

Introduction

When building web interfaces one must respect the '3 layers' and the roles they play: XHTML for content, structure and semantics, CSS for presentation and Javascript for behaviour. When constructing the behaviour layer using Javascript one must keep it Humble, it should not impose itself on the semantic layer by requiring you to add non-semantic XHTML tags or attributes. Neither should it attempt to exert control over the presentation layer, that's the job of CSS. Humble Javascript understands its place in the platform and respects the role of the other two layers. Writers of humble Javascript understand its role and do not fail to use it for what it does best.

One of the strengths of the web interface is it's portability. Each layer can be made completely portable between webpages and interfaces. However, failure to seperate the 3 layers decreases their independence. If you start polluting your XHTML with behavioural logic then it becomes less portable, so does your Javascript if you include presentational style information. The ideal of Humble Javascript suggests you should be able to remove the javascript altogether and still have a completely functioning page. Similarly removing the CSS should not leave a dysfunctional page.

The Hooks

When you start to think this way you notice how easily it comes together. It seems almost natural. The semantic layer is the basis for any web interface and the only indispensible layer, the other two layers are applied over the top. XHTML has ready-made hooks for for just style of use, making applying the other two layers a little easier: The tag, the ID and the class.

Hook
XHTMLCSSJavascript
Element tag<tag />
tag {}
document.getElementsByTagName('tag')
Element ID
<tag id="id" />
#id {}
document.getElementById('id')
Element Class
<tag class="class" />
.class {}
element.className

The Guidelines

Often all Humble Javascript amounts to is a few simple guidlines:

In use it means:

Examples

The Humble Javascript ideal came about when writing my Real Easy Validation library . My first goal was to make validation as simple and unobtrusive as possible. So I made the most of the elements' class names to describe the validation requirements and then Javascript to describe the logic. Which worked well for simple things like 'validate-number'. But sometimes validation requirements are more complex, for example, if a number is between a minimum and maximum amount. The temptation is to add this logic to the XHTML and keep the Javascript generic. For example do things like write complex class names - 'validate-number-min-10-max-100', or to add custom XHTML attributes - min="10" max="100". I had many emails suggesting these approaches and a few people even extended the library to do this for their own purposes.

However, As a strong believer in semantic XHTML this just didn't feel right because you are removing logic from javascript and adding it to XHTML. Logic is what Javascript does best and XHTML should be left to handle semantics. So according to my ideal I'd simply create a custom class name like 'validate-score' making sure it was a meaningful name relative to my needs and leave the min/max stuff to a custom Javascript validation function. 'validate-score' is a meaningful class name that is easily portable between webpages. In our example here 'validate-score' is a number value between 10 and 100, the logic of which is defined in a single javascript validation library. If the conditions of 'validate-score' change and we have several forms that utilise this concept we have saved that mangement overhead say if we'd instead used XHTML element attributes to define the minimum and maximum: it need only be changed in one spot, the javascript library, instead of the XHTML for each form. It can also be repurposed for other things like CSS (to make 'score' fields look a certain way) or other behavioural Javascript functions (to add a score slider control to each score field).

Benefits

The benefits of Humble Javascript become clearer the more you use it. I find the resulting web interfaces are accessible and compatible to a high degree and often in ways that are surprising. For example, you might find that your web interface offers a highly usable experience through a PC web browser and when you test it on a mobile device you happily discover it works perfectly fine there too.

Humble Javascript does not degrade the browser experience. For example if you use my table sorting script with Javascript turned off and CSS enabled you will find the XHTML table still works just fine. Similarly if you turned off the CSS and enabled Javascript, table sorting will remain functional.

I also find it makes managing a website easier when all the XHTML, CSS and Javascript sources are kept seperate. Fiddling about with CSS in javascript or logic values in HTML is just impractical.

Counter-Examples

There are many Javascript libraries and widgets available on the web. Some libraries are written so that everything is done in script, others remain generic so that all logic is done in XHTML. Also when making a javascript library for common use, one always has to consider how much work to make the implementer do to use it, some libraries are written for people comfortable using javascript and some for people who don't want to write any. I prefer to encourage a balanced approach - to write Javascript where appropriate and to use XHTML and CSS effectively.

The Fuzzy Bits

Obviously, as an ideal, strict adherence is not realistic and possibly silly, There are a few areas where the 3 layers overlap. For example if moving an element or creating a transition effect manipulation of CSS must be done in Javascript. Sometimes the use of ':hover' in CSS is desirable. And XHTML offers a few important behavioural elements like the 'label' element.

That's It

Well, there you have it; the (long-winded!) reason why I write Javascript the way that I do. I get a lot of emails and comments asking 'why dont you...' and I intended this post to be an explanation of why I don't. For me this just works. It feels like the right way, the natural way to create web interfaces that work well.

Some of my inspiration comes from:

6 Comments

#1
On the January 28, 2007, Alexandre Plennevaux wrote:

Hi Andrew,
I came to you in the first place exactly because of the way you make JS, CSS and XHTML work nicely together - in fact, using each technology for what it is meant to be used, and not against it. It sounds normal, yet not many achieve in doing it as elegantly as you.

Very glad to read a good breakdown of the thinking behind. 

#2
On the February 15, 2007, Lewis wrote:

Some useful information here. Thanks.

I'm trying to develop an online questionnaire in such a way that the total score of all the variables (questions) is added at the click of a button. Are there any free scripts that might give me a clue that you know of?

#3
On the February 16, 2007, Lewis Stratton wrote:

You emailed me yesterday, but I get an error message each time I try to respond. My enquiry from yesterday was genuine. Found a partial solution after leaving my post here. Hoping I can work out the last bit!!

#4
On the February 16, 2007, Lewis Stratton wrote:

I have attempted to implement Javascript in a stress survey, but get "Expected J" and "Expected Object" errors. Wondered if you could offer some guidance?

Survey is located at www- -dot- longerstrongerliving - dot - com/stresscalc.htm

"Total Score" box will not display sum of responses.

#5
On the February 17, 2007, Andrew Tetlaw wrote:

Hi Lewis, you should avoid naming a field with a number. called them a1, a2, etc. Also the eval()s are not needed.

#6
On the February 19, 2007, Lewis wrote:

Many thanks Andrew. I would have had no hope of picking this!

Appreciate your time and help.

Leave your comment


HTML tags will not work. Your email address will never be displayed. If you have a Gravatar we'll display it.

Random outings from a chaotic mind

The Dexagogo Rocket Australian Web Industry Association logo

Delicious

Twitter