JavaScript is a Ghost

Table of Contents
I was talking recently with a fellow developer and the topic of progressive enhancement came up. I asked what her ideas on the topic were and we discussed old browser support, IE and old IE. This is a common conversation I have quite frequently. We frequently associate progressive enhancement with the old—old developers, old browsers, old ideas. What a drag.
The Haunting fragment anchor
For me progressive enhancement is about the absence and presence of features. That is what excites me most about making websites—planning for the unknown.
In my daily work the feature I plan around the most is JavaScript. The following allows me to plan for the unknown and deliver an effective experience in JavaScript’s absence:
document.getElementsByTagName('body')[0].className+=' js';
This will test if JavaScript is available and if passed adds the class of .js
to the body element. A common example of where this is applicable would be a navigation menu that’s controlled with JavaScript.
<nav class="navigation">
<button class="menu">Menu</button>
<ul class="navigation-items">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</nav>
A common way to add the functionality we need for the menu would be to set the navigation items to display:none
or visibility:none
by default and then toggle the display or visibility when the .menu
button is pressed. We run into problems though if for any reason JavaScript fails. The .navigation-items
will become inaccessible. This is where the js class helps.
/*default styling*/
.navigations-items {
property:value;
}
/*close state with JavaScript present*/
.js .navigation-items {
visibility:hidden;
max-height:0;
}
/*open state with Javascript present*/
.js .navigation-items.open {
visibility:visible;
max-height:the height we would like our menu to be;
}
Without JavaScript the navigation items get styling and work as intended but if JavaScript becomes active the navigation items become hidden ready to be activated by the menu button. The default styling for the navigation items is written as if JavaScript is an apparition. A Feature that may or may not appear depending on any number of different factors.
So what happens to the menu button when JavaScript is not available. A button that doesn’t do anything isn’t very helpful. A good way to solve this problem would be to add the button to the document with JavaScript.
var addGhost = function() {
// create a button
var ghostButton = document.createElement('button');
// create a textnode
var buttonText = document.createTextNode('Menu');
// add the textnode to the button
ghostButton.appendChild(buttonText);
// set a class for the button
ghostButton.setAttribute('class','menu');
// vars for targeting our menu within the DOM
var navItems = document.querySelector('.navigation-items');
var nav = document.querySelector('.navigation');
// insert our button right before the navigation-items
nav.insertBefore(ghostButton, navItems);
}
With this approach the menu button is conjured only if JavaScript appears.
Treating JavaScript like an anomaly I am able to make websites that are more fault tolerant. To me JavaScript is a ghost. Even in it’s absence it still makes it’s presence felt but remains invisible.
Old is New fragment anchor
Some folks believe progressive enhancement had it’s time but is no longer relevant. To this I would say than let’s look to the future. For example:
<input type=tel>
The input type of telephone is a native feature of HTML designed to be future friendly yet fault tolerant. If the feature is supported it works as intended. If not it works like a input type of text.
The same goes for some of the features in the new Service Worker API. Features like client side caching and working offline will only work in browsers that support these features and silently fail in browsers that don’t.
In many instances my life is made easier by approaching my work with a progressive enhancement mindset because thats how many native features in HTML are designed. To work when supported and remain invisible when not.
Back to Table of Contents
6 thoughts on “JavaScript is a Ghost”
Interesting read, thanks!
I’m glad you enjoyed it.
Excellent article Paul – explaining the concept concisely in terms that are easy to understand and relate to.
Thanks for the kind words Rowan.
Very helpful. Many thanks.
Happy to help.