ppk on JavaScript: Context
JavaScript is used in the context of a Web page. This is obvious, but it has a few consequences that haven’t always been properly appreciated. JavaScript is embedded in an environment that also uses HTML and CSS, and in which usability and accessibility are essential elements. After all, a script must add something useful to a site, and the site must continue to work when JavaScript is disabled or entirely absent.
This chapter—in fact, my entire approach to JavaScript programming—is heavily influenced by the standards-compliance CSS revolution that has changed Web development. Therefore it’s fitting to start this chapter with a quick summary of the CSS revolution and its impact on JavaScript.
A: The CSS revolution
As we saw in 1C, in 1998 (when Netscape and Explorer 4 couldn’t agree about anything), a group of concerned Web developers united in the Web Standards Project (WaSP), to do something about the ludicrous proprietary elements of JavaScript and to promote the use of CSS for defining the presentation of Web sites. Their main message was “Follow the standards,” and they aimed this message at both browser vendors and Web developers.
At first, WaSP and its sympathizers concentrated on promoting CSS. There were various reasons for this, the most important being that using CSS in Web-site creation formed the clearest break with the past. JavaScript didn’t really enter the equation yet, both because CSS was enough of a challenge to occupy the best minds in Web-development land for years, and because back in 1998 the average JavaScript was badly written, badly thought out, and completely inaccessible.
Besides, it was relatively easy to get browser vendors to start working on their CSS implementation because it was a new technology that was not yet weighed down by millions of implementations on millions of sites. In contrast, JavaScript was hampered by the countless existing implementations of the browser-specific document.layers and document.all DOMs we briefly discussed in 1C. CSS offered the possibility of a clean slate.
One of the drawbacks of this focus on CSS was that, in the minds of some standards supporters, JavaScript became equated with “inaccessible.” You’ll still encounter this misconception every now and then, even though, as we’ll see later in this chapter, JavaScript and accessibility can co-exist in harmony, as long as you take some precautions.
Unobtrusive scripting
In 2002, Stuart Langridge coined the term “unobtrusive scripting,” which represented the first serious attempt to embed JavaScript in the new theory of CSS-based, standards-compliant Web sites.
An unobtrusive script should have all of the following traits:
- It should be usable, i.e., it should confer a definite usability benefit on the site.
- It should be accessible, i.e., if JavaScript doesn’t work, the page should remain readable and understandable, although the loss of some usability is inevitable.
- It should be easy to implement; typically, a Web developer has only to include the script itself and add a JavaScript hook in the document, and the script works. We’ll discuss JavaScript hooks in 4B.
- It should be separate; it resides in its own .js file instead of being scattered through the HTML.
In theory the first idea has been present since JavaScript’s birth, but it has usually been disregarded by programmers eager to show off JavaScript’s capabilities. Never mind if these capabilities don’t confer a usability benefit—they’re cool!
The other three ideas were new. Accessibility and JavaScript were generally held to be mutually exclusive, and most old-school JavaScript developers decided that their applications were too advanced to ever become accessible. That’s nonsense, of course, but it is powerful nonsense that has held JavaScript in thrall for far too many years. We’ll discuss JavaScript and accessibility in 2E.
Ease of implementation requires JavaScript hooks, and they became possible only with the advent of the W3C DOM. This was the sole idea that was new for technical rather than psychological reasons. See 4B for more information.
Separation, lastly, was an idea borrowed from the CSS revolution. If you should separate your HTML and CSS, it’s logical to separate your JavaScript from both of them, too. Before we can discuss the three kinds of separation, we first have to study what we’re going to separate.
The three layers
A Web page consists of three layers (and yes, these are the ones that need to be separated from each other):
- HTML structure.
- CSS presentation.
- JavaScript behavior.
Figure 2.1 The three layers of a Web page. The HTML structural layer is the required basis, and the CSS presentation and JavaScript behavior layers are built on top of it.
The HTML structural layer is the most basic part of the page. The HTML tags form the structure of the page and give meaning to its content. For instance, if a certain text is marked up with an <h1>, it’s a header and should be treated as such. Browsers (or, more generally, user agents—programs that interpret HTML) are expected to distinguish this header from the surrounding normal text, for instance by displaying it in bold and in a larger font, or by pronouncing it louder or slower. Once you’ve created structurally correct HTML, you can be reasonably certain that most user agents, hence most users, will recognize a header as a header.
The purpose of the CSS presentation layer is to define how your HTML should be presented. CSS allows you to specify colors, fonts, leading, and other typographical elements, as well as the general layout of the page, for instance, “The navigation block goes next to the content block.”
The JavaScript behavior layer adds interactivity to an HTML/CSS page. As soon as you want something to happen when the user mouses over an HTML element, you need JavaScript to implement the effect.
Every Web page needs an HTML structural layer—without HTML, there is no Web page. However, the CSS and JavaScript layers are optional. Old, obscure, or unusual browsers may not support CSS and/or JavaScript, in which case one or both layers may go missing—the presentation or behavior instructions are never executed.
Figure 2.2 If a browser can’t handle JavaScript, obviously the behavior layer won’t work. Will your site survive that experience?
The consequence of this state of affairs is obvious. Any site must be able to survive the demise of the behavior layer (or the presentation layer, but that’s a much rarer occurrence). In other words, a site may not totally rely on JavaScript, but must remain accessible when JavaScript doesn’t work. We’ll get back to this in 2E.
Separation of concerns
Another point raised by the division of client-side code into three layers is the separation of concerns. In general, it’s best to manage each of the three layers separately. At the most basic level, this is done by making sure of the following:
- The HTML is structural, not too complex, and makes sense without CSS and JavaScript.
- The CSS presentation layer and the JavaScript behavior layer reside in separate .css and .js files.
Separating concerns makes for easy maintenance. When you use separate CSS and JavaScript files, it’s easy to link to these files from all pages in your site. This has obvious maintenance advantages: if you open the .css file and change, say, the font size from 12px to 0.8em, this change will immediately be propagated to all HTML pages that link to that .css file.
Besides, separation allows you to change the entire CSS presentation layer to give your site a new design, without having to recode either the HTML structural or the JavaScript behavior layer.
The three separations
As you see, separating concerns makes your site’s code cleaner and easier to maintain. In the next section we’ll discuss the gory details of the three separations:
- Separation of presentation and structure (CSS and HTML);
- Separation of behavior and structure (JavaScript and HTML);
- Separation of behavior and presentation (JavaScript and CSS).
All three influence the way we should write JavaScript.