31 March 2008

Progressive degradation

I should start this post with a disclaimer. I did not discover or invent this technique. It was suggested to me by a now ex-colleague, Marcus. He also does not like what I have named this technique. But you can make your own mind up.

We should by now all be aware of progressive enhancement, what it is and why to use it. Well, progressive degradation actually assists with progressive enhancement and in some ways turns the idea on its head to make life easier and simpler. Whenever I have employed progressive degradation, I have found things easier to develop and maintain.

Progressive enhancement generally involves writing high quality semantic markup and then layering onto that additional elements which do not in themselves add additional meaning but enhance the visual presentation of the content of a web page or make it easier and nicer to use.

Generally progressive enhancement will mean layering CSS on to the markup to make the web page look nice, and JavaScript to make the web page easier and nicer to use. Progressive degradation turns that idea on its head.

With progressive degradation, we still need high quality semantic markup. That is always the base. We are still going to layer CSS on to the markup to make the web page look nice. The big change is with the JavaScript.

Using progressive enhancement, we would write the CSS in such a way that if the user does not have a JavaScript enabled browser, the site works well and looks correct. If the user does have a JavaScript enabled browser, the JavaScript code itself would make changes to the way the CSS is applied (and perhaps to the markup as well) to give the web pages a slightly different look and additional behaviours.

Using progressive degradation, we apply the CSS to the markup in the assumption that the user has a JavaScript enabled browser. Let me just make that clear. We make the assumption that the user has JavaScript enabled within their browser.

So where is the magic? The trick is that we include an additional CSS file for those users who DO NOT have JavaScript enabled in their browser which will re-style the content to be usable without the JavaScript enhancements.

This technique is not suitable for all occasions, but when I have employed it within a website, I have found a way to use it for every enhanced element.

The major advantage of progressive degradation is that there is no page flicker as the content is altered by JavaScript code even when the JavaScript code is run on page load as the CSS code that is loaded with the page sets up the page for the JavaScript enhanced version from load.

Its an extremely simple technique to apply and the following code is all you need:

<noscript>

<link rel="stylesheet" href="noscript.css" type="text/css" media="screen" />

</noscript>


As you can see, all that is involved is the addition of a CSS file inside noscript tags. Whilst this does make the markup for your web page invalid, I believe it is a small price to pay for the power it brings. To demonstrate that power, an example could be useful.

The example I will use is that of a form which will add an item to a list. Without JavaScript, the form will always be visible. With JavaScript, there will be an add button which when clicked will show the form. How the form submission is handled here is not important but one could use an AJAX request for those user agents which support it and a postback cycle for those which do not.

The 2 versions of this page element look as follows:

With JavaScript enabled:



Without JavaScipt enabled:



The markup is as follows:

<div id="ListContainer">

<ul>

<li>Item 1</li>

<li>Item 2</li>

</ul>

<form action="page.html" method="post">

<label for="NewItem" id="NewItemLabel">Add item</label>

<input id="NewItem" type="text" />

<input type="submit" id="SubmitForm" value="add" />

</form>

</div>



The pertinent CSS for the purposes of this article is:
#NewItem, #SubmitForm {

display:none;

}


This CSS will hide the input field and the submit button.

The following (somewhat rough) JavaScript will make the progressive enhancement work so that when clicking on the label for the form field, the input field and submit button will show:
<script type="text/javascript">

window.onload = function() {

document.getElementById("NewItemLabel").onclick = function() {

this.style.display = "none";

document.getElementById("NewItem").style.display = "block";

document.getElementById("SubmitForm").style.display = "block";

}

}

</script>


So, we now have a working form module as described above. When the page loads, some elements are hidden - there is no flicker whilst the JavaScript kicks in on page load and hides the relevant elements as they are already hidden! Clicking on the label will hide the label and show the relevant elements.

Now for the progressive degradation:
<noscript>

<style type="text/css">

#NewItem, #SubmitForm {

display:block;

}

</style>

</noscript>


And that is all there is to it. Without JavaScript enabled in the web browser, the user will see the complete form. With JavaScript enabled, the user gets an enhanced experience. If you re-read the last 2 sentences, you will notice how right it sounds and yet we are mixing the concepts of progressive enhancement with those of progressive degradation.

Of course we could take this example much further, writing some JavaScript to allow the user to return the page to its load state if they changed their mind and did not actually want to add another list item. We could write code to handle the form submission etc and all this would be progressive enhancement, but progressive enhancement made even easier by starting with the concept of progressive degradation.

The key to how progressive degradation makes this easier is that we know the non-JavaScript version of the page will work perfectly and we can add as much progressive enhancement as we like and concentrate on writing fantastic JavaScript to enable exciting but as always simple and light-touch enhancements to the web pages we build.

24 March 2008

JSquared 1.0 released

Just a quick note to point you to JSquared 1.0 which is now in release. Please feel free to feedback on your thoughts.

18 February 2008

JSquared auto filter list

One of the updated objects released with JSquared 1.0 beta 2 is the auto filter object. This is a powerful object for filtering lists and is proving useful in a variety of circumstances, not least the creation of auto complete drop down lists for instance for searching.

At present the object only handles static lists, but by the time JSquared 1.0 is in final release, it will support live lists and a host of further options. That is to say that you would be able to provide a JSquared ADIJ or JSquared AJAX object as the list of values and the auto filter object will use that object to retrieve the list of values each time it needs to perform a filter.

The object is designed to work with a text input field and to respond to key presses to perform a filter. Within this structure, it is quite configurable. Lets have a look into the object and how to use it.

To initiate the object, create an instance using the "new" keyword. The constructor of the object takes 3 parameters, the third of which is optional:
  1. field - a reference to the DOM node which the auto filter object will respond to and work with
  2. data - the list of items to filter as an Array
  3. options - some options for how the object should perform
The options
  • objectMember - the array of data to filter can be an array of objects. If it is, the auto filter object needs to know which member on each object in the array contains the filter data. This option defines that.
  • minLength - the minimum number of characters to be entered into the text field before filtering starts. Defaults to 1.
  • hoverCssClass - the css class to add to the node which is hovered over (or selected) by the user once the filtered list is displayed
  • matchAnyCharacter - a boolean value which if true will match the characters entered into the text field against any character in the data list. If false (the default) it only matches from the start of the items in the data list

Events
In addition to these options, you can respond to various events. Pass in event handlers with the options as follows
  • onItemBound - fired when a matching item in the data list is found and bound to the document
  • onItemSelect - fired when the user selects an item from the filtered list
  • onFilteredListDraw - fired after the filtered list of items is added to the DOM tree
The first 2 events defined above run in the scope of the DOM node representing the relevant filtered list item. They both will get passed a parameter containing the original data for that list item. If the original data list was an array of objects, the whole object will get passed.

The third event defined above runs in the scope of the list of items.

The HTML
When the user enters a value into the field which is to support the filtered list, a list of matching items is added to the DOM immediately after the field. Assuming the value in the field is "value", this list will by default appear as follows:

<ul class="autoCompleteList">

<li><strong>value</strong> 1</li>

<li><strong>value</strong> 2</li>

<li><strong>value</strong> 3</li>

</ul>


This HTML can be styled by CSS. The css class defined for the currently hovered over item (or "hover" by default) is added to the appropriate list item.

Selecting an Item
When the user selects an item either by clicking on the item in the displayed filtered list or by using the keyboard (up and down cursor keys to choose an item and enter to select it), the value of that item is written into the field.

That is pretty much all there is to it. Its quite simple really!

JSquared Packages

With the release of JSquared beta 2, I have provided one file containing the full library which is also minified. This file weighs in at 29Kb! I would always recommend using JSquared in its componentized format, just including what you need at any time.

JSquared 1.0 Beta 2

JSquared 1.0 Beta 2 has just gone live and is available for download now.

This version has a number of enhancements over beta 1, not least the deployment method! You can now upgrade from beta 1 to beta 2 by just replacing the old code with the new. I have also provided full versions of the library with all its components in one file in both compressed and uncompressed formats.

There have been a number of improvements and additions since beta 1:

  • Better DOMReady handling
  • Much faster "trim" method on strings
  • New image rollover object - back to the future!
  • Delegate handling pattern
  • New auto filtering object. Highly configurable.
  • A URL manager object for adding entries to the browser history and allowing bookmarking in an AJAX application
  • Loads of little bug fixes
For those who still want it, beta 1 is still available for download as well.

Keep an eye on this blog for more information about all the JSquared features. You should already know about ADIJ!

12 February 2008

Lack of posts

Apologies to all those avid readers out there for the recent lack of posts on this blog.

This is what happens when you are less than 3 weeks from being married!

I will attempt to complete my series on Asynchronous JavaScript techniques (only 3 more parts to go) before heading off to Thailand for 2 weeks for our honeymoon.

Roll on March 2nd...

4 February 2008

HTML 5 and Web Standards

With the recent publishing of the W3C HTML 5 Working Draft, and the debacle which is IE versioning through meta tags, I have been having some thoughts about web standards.

It so happens that I am not the only one! Molly E. Holzschlag has also been thinking. Whilst her thoughts are somewhat more drastic than mine, I felt it time to put forward my thoughts on the next generation of HTML on the web.

HTML 5 is a massive specification introducing many new tags and attributes of which without a doubt my favourite is the irrelevant attribute. I would personally be quite happy to wrap large parts of the spec in such a tag!

I believe strongly in simplification and I do not believe HTML 5 simplifies HTML. What I think we need is less not more. There is one very specific point which grates. HTML should enforce an XML syntax - tags should have to be closed and have to be well formed. HTML 5 allows unclosed tags and this to my mind is a step backwards. Indeed, I see the spec contains code a bit like this:

<dl>

<dt>Radius: <dd> <meter min=0 max=20 value=12>12cm</meter>

<dt>Height: <dd> <meter min=0 max=10 value=2>2cm</meter>

</dl>


This is some ugly stuff!

I believe HTML 5 should actually be XHTML 5 (or version 2 or whatever version you like!). It should contain a small set of semantic tags including paragraph, emphasis, lists, audio, video, anchors, images, divisions (or sections) amongst others, creating a small set of recognised tags with well defined default rendering for each. As an author, I should be allowed to create ANY OTHER TAG I LIKE as long as it is well formed XML. The default rendering for each unrecognised tag should be as an inline element and they should offer no semantic meaning.

The tags I "create" should be able to be styled through CSS and accessible as DOM nodes via JavaScript.

Its simple. Or is it too simple?