Rich GUI is one of the requirements of nowadays web. The look and feel of websites is getting closer to desktop applications. The widgets are getting more and more intuitive. But the web developers, as well as customers ordering the web projects, should always keep accessibility and semantics in mind. The web is information at first and impression afterwards.

Technologies should enhance the real world, but not vice versa. Therefore, as the owner of the content, you should be interested to distribute the information in all available ways. The content should be accessible in standard modern browsers as well as in Javascript-disabled browsers, screen readers, or small-screen devices like PDAs and cell phones. The presentation (CSS) and special effects (Javascript) should go on top of the content (XHTML). These parts should be separated into different files and not mixed-up. The general rule of thumb tells that if you switch off the style, images, Javascript, or all together, the visitor should still be able to read the content and navigate through the website. Imagine, that you came to a concert in a different city and you need to find out what buses are going to the concert hall. Then you open the local website of the public transport system in your mobile phone and check your traveling route. If this website is not accessible to you because of obligatory specific Javascript widgets which are not supported by your mobile, you will probably be late to the concert and your day will be ruined.
The semantic web is a concept of rules for informational data, which would allow represent, query, and modify data using different technologies. Instead of unreliable screen scraping for getting specific information from the page, it should be possible to parse the content using the DOM and to get the whole structure of the page. This is not only useful for search engines, but also for third-party web and desktop applications that may reuse your content in different mashups. For example, if have a simple informational website for the restaurant you own, with its location and probably a dynamic and nice map, there could be another company which would make a web crawler collecting information of different restaurants and hotels, and parks, showing them in one combined map with ratings of each place, comments, and recommendations. If the content of your website is not semantic, you’ll hardly get additional attention from third-party projects.
No matter, what the business model for the website is, if the company is future-oriented, the website should have the structural content separated from presentation and logics. And the content should be accessible and navigable without Javascript nor CSS. All the rich GUI effects should be added additionally by Javascript, when it is enabled. Forget all the tutorials and examples creating content on the fly with document.write or adding event handlers for HTML element directly in the markup. The Javascript should be included from separate files and it should influence the content using DOM after the page is loaded. This concept is called unobtrusive Javascript. The separation of different layers means also faster loading as Javascript and CSS files are usually downloaded once and taken from the browser cache for other requests.
DON’T:
XHTML:
<a href="http://aaiddennium.com/blog/"
onclick="window.open(this.href,'','width=800,height=600');return false">
My Blog
<script type="text/javascript">
/* <![CDATA[ */
document.write("(opens in a new window)");
/* ]]> */
</script>
</a>
DO:
XHTML:
<a href="http://aaiddennium.com/blog/" class="new_window">
My Blog
</a>
Javascript (included from a separate file):
window.onload = function() {
var aElems = document.getElementsByTagName("a");
for (i=0, iLen=aElems.length; i<iLen; i++) {
var oEl = aElems[i];
if (oEl.className.match(/\bnew_window\b/)) {
var oT = document.createTextNode("(opens in a new window)");
oEl.appendChild(oT);
oEl.onclick = function(e) {
if (!e) var e = window.event;
var oLink = e.target || e.srcElement;
window.open(oLink.href, "", "width=800,height=600");
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
};
}
}
}
Moreover, there is a concept of creating fully functional website without special effects and then adding Javascript to change the default links to Ajax-based content loaders. This concept was called Hijax by Jeremy Keithin in his book Bulletproof Ajax. However the Hijax approach has it’s disadvantages as well. For example, the standard Back/Forward functionality makes no sense with Ajax data loading. And it’s pretty expensive to duplicate all the functionalities making one server-side and one client-side approach.
I would say, that the usual link navigation should be used in most cases, and Javascript should be added only as specific widgets or for specific pages. Javascript can overwrite the default functionality. For example, external links can be opened in new popup windows by Javascript, or some small forms can be opened in new Ajax-based dialog boxes. The original link, turned into Ajax-based-functionality switcher, in some cases might lead to a new page, telling how to enable Javascript or where to get a modern browser. Or it can be a hash (#) link, leading to some place with information in the same page.
Each page should provide information, that the website is best experienced when viewing with Javascript-enabled modern browsers. This message could be hidden dynamically by Javascript on the page load, or even better, it could be written into the <noscript> tag which is shown when there is no Javascript. If you choose to hide the message by Javascript on the page load, you might dislike the flickering of the view as the message shows and then disappears. You can avoid that flickering, dynamically adding display:none not to the containing element by id after the page loaded, but to the additional CSS rule for the selector by that id while the page is still loading. The head section of the HTML document is always executed before the body is shown.
DON’T:
window.onload = function() {
document.getElementById("warning_js").style.display = "none";
}
DO:
function dyn_css_rule(sSelector, sCssText) {
var oCss = document.styleSheets[0];
if (oCss.insertRule) {
oCss.insertRule(
sSelector + " {" + sCssText + "}",
oCss.cssRules.length
);
} else if (oCss.addRule) {
oCss.addRule(sSelector, sCssText);
}
return sSelector + "{" + sCssText + "}";
};
dyn_css_rule("#warning_js", "display:none");
Moreover, you should never dynamically modify the style of HTML elements directly. CSS is the responsibility for presentation layer, not the logics layer. Javascript should manipulate semantical class names. Then the presentation layer decides what to do with, let’s say, not important elements: to hide them, add some transparency, make the font smaller, or move them to different positions.
DON’T:
function toggle_visibility(sId, bVisible) {
document.getElementById(sId).style.display = bVisible? "block": "none";
}
DO:
function toggle_visibility(sId, bVisible) {
var oEl = document.getElementById(sId);
var sClasses = oEl.className.replace(/\s*hidden\s*/g, " ");
if (bVisible) {
sClasses = sClasses + " hidden";
}
oEl.className = sClasses;
}
Even if you are a professional Javascript coder, it is useful to use Javascript frameworks instead of raw Javascript. The code you write will be cleaner as most boring routines are already implemented in the framework. The development will get faster as soon as you get used to it. And the product will be more reliable as the framework is tested on different browsers by large communities. The framework you choose, should support unobtrusive Javascript approach and strict XHTML. I personally prefer jQuery, but you can choose any other framework which seems easily adaptable for you.
DON’T:
var aElems = document.getElementsByTagName("div");
for (i=0, iLen=aElems.length; i<iLen; i++) {
var oEl = aElems[i];
if (oEl.className.match(/\bspecial\b/)) {
oEl.onclick = special_function;
}
}
DO:
$("div.special").click(special_function);
When working with Ajax, you should also understand that the speed of Internet is not the same for all visitors. So even if it takes a second for you to load some JSON-formatted data, the same request might take about 15 seconds for another user with sloooow Internet connection. So the website should show different identifiers for different statuses of “initial state”, “loading”, “result”, and “error”. Otherwise the visitor might click on the same widget multiple times trying to make it functioning. And this might lead to accidental duplicates and confusion. Sometimes it might be also useful to have a button for canceling the current request.
It might be strange for you that I didn’t show you how to create any full-featured widget as rating management, auto-completion or some calender. But the purpose of this entry was the introduction to the client-side coding of a better quality. All the rest depends on your creativity and business requirements. The experience comes from practicing.
Further reading: