Progressive Enhancement != "No JavaScript"

So Nicholas Zakas recently gave this presentation, explaining why he thinks we rely too heavily on JavaScript nowadays. Jake Archibald followed up with this article, giving more reasons why relying on JS can be bad.

I agree with every word that both of them have said: HTML and the DOM should be our foundation. A web thing should always serve something to a user when JS is either disabled or broken and the details regarding performance and reliability are as relevant today as ever.

But both Nicholas and Jake still seem to intrinsically tie progressive enhancement to JavaScript.

I think this gives people the wrong idea, and in fact can be hugely limiting.

Cracking the peanut M&M

The classic model of progressive enhancement was the peanut M&M – content, wrapped in a presentation layer, then a behaviour (scripting) layer.

But I think even this is misleading. It implies that the behaviour rests on the presentation layer. What if the presentation layer can't be experienced? (Think users with sight impairments...)

Of course we can have behaviour which isn't related to styling. Sure it can work with the presentation layer, but if one is removed, there's no reason why the other shouldn't still stand to some degree.

It also suggests that those are the only 3 variables.

A dodgy analogy

A much better model is a table where content, presentation and behaviour are the legs. You need to position the legs (read as: "design your web thing") so that, if presentation or behaviour were removed, the table still stands.

How do we keep a table standing if it only has one leg? Make that leg (your content – i.e. markup) central and ensure it can support as much of the weight (functionality) as possible, unassisted.

But this is still just a fraction of what progressive enhancement is about, and what it can do.


To me, progressive enhancement is about managing compatibility: ensuring our web thing works for as many different browsers, different devices and different users as possible.

We provide a basic experience which serves the most limited users, then enhance that for those with the capabilities to experience more.

The ability to execute JavaScript is just one of the many, many possible differences between 2 users' capabilities.

There are 3 reasons for differences between browsers:

  • Features – standards-compliant capabilities (HTML5, CSS3, JS APIs, etc)
  • Bugs – situations in which a browser isn't compliant (an incapability)
  • Plugins – capabilities added (or sometimes removed) by additional software

And there are hundreds of each of those.

There are dozens more reasons for differences between devices and an infinite number of reasons for differences between users themselves – any of which can have an effect on whether or not your web thing "works" for (i.e. is accessible to) a user.

Yes, browser/device support and accessibility are just two sides of the same coin.

All of these differences – including those of the device and the user – can be described by posessing or not possessing certain capabilities. We can guess at which capabilities might be available through our knowledge of browser support, but that's yet another layer to consider. It's easier to just assume that a user may have any set of these capabilities.

Progressive enhancement lets us provide different experiences based on support for any of those capabilities. Why limit it to JavaScript?

Capabilities and dependencies

If a feature of your web thing uses an HTML5 feature – say the <video> tag – it depends on that capability being present, much like a software dependency. If that capability isn't available, that part won't be experienced.

Sure, you might provide a fallback... but really that's an alternate feature, with its own dependencies.

If the feature isn't essential and it doesn't matter if it isn't there, let's call it an enhancement... oooh, that word sounds familiar!

An even dodgier analogy

So any of these capabilities could be considered to be 'legs' of our table. That's a lot of legs. And if some features are optional – i.e. they're enhancements – maybe they're separate tables, chairs and, er hatstands...? – which we don't mind falling over.

Right, the analogy's gone to shit. Time for a new one.

Let's think of it as a game of Angry Birds – but one where you're on the pigs' side:

Dependencies: the acrimonious avian way

Our app's features are the precariously balanced blocks on top; which are supported by their dependencies: the browser capabilities required to keep them from falling... but our testers (those pesky birds) fly in and find platforms and users which don't have the capabilities we thought we could depend on – while our poor users are stuck in the middle.

The aim is to arrange your features on top of the browsers' capabilities such that, no matter what the birds throw at you, enough of your features stay standing to keep your users happy.

It doesn't matter if a few blocks (features) fall off (aren't experienced) – as long as they don't come crashing down on your users' (pigs') heads.

Sorry for calling your users "pigs". I swear it's just for the sake of demonstration.

JavaScript is just one of those supporting beams.

"Modern Web Apps"

As much as we'd like it to be the case, there are a lot of things you simply can't do without JavaScript.

If your app can lean on behaviourless HTML as much as possible, that's great – and the benefits have been explained by Nicholas and Jake. But sometimes it just isn't practical.

Ultimately, many web things nowadays are very much programs rather than documents (even if the line is incredibly blurry). When have you ever heard another kind of software being told it must function without executing any lines of code?

A baseline

So what if we assume JavaScript is always available? Does progressive enhancement go out the window?

Of course not: I've just pointed out that there are thousands of other capabilities which a user may or may not have. You can still provide enhancements conditionally based on:

  • HTML tag support
  • CSS feature support
  • the presence of various JavaScript APIs
  • Network connection quality
  • Screen area offered by the device (responsive design!)
  • Other device features, like location awareness and hover-capable input types
  • The user's quality of sight or hearing

That's still progressive enhancement and it's still, in my opinion, the best way to handle the vast differences between your target users and the devices and browsers they use.

It's up to you to define your "minimum spec", which depends on your use case, business case and user base – as well as concern for all of the things Nicholas and Jake discussed.

Maybe that's "just HTML4", maybe that's "HTML4 + JS", or maybe it's "HTML5 + JS + features X, Y and Z".

Just an alternative viewpoint

As I said earlier, I don't disagree with anything Nicholas and Jake said. It's completely correct, well-founded, good advice. However, whether or not you follow that depends totally on your use case and business case.

And even if you decide that JavaScript is a mandatory requirement, that doesn't mean that progressive enhancement, accessibility and all those good things don't apply to you.