This post was originally written in 2015, but upon re-reading it today, it still (just about) holds up, so I finally hit publish.

I had thought that an EdgeConf panel would be about developers not using JavaScript because they were more interested in building high end web apps, full of WebRTC, Web Audio and the like. But it's not.

I had the pleasure of introducing the Progressive Enhancement panel and contributing to the panel in 2015. For my introduction, I ran some "research" and did some pondering about what exactly is progressive enhancement.

READER DISCOUNTSave $50 on terminal.training

I've published 38 videos for new developers, designers, UX, UI, product owners and anyone who needs to conquer the command line today.

Here's the thing: after getting responses from 800+ developers (on a Twitter poll), I've come to realise that most developers, or certainly everyone following me, everyone watching (the EdgeConf stream), everyone reading, see progressive enhancement as a good thing. The "right thing" to do. They understand that it can deliver the web site's content to a wider audience. There's no doubt.

There's accessibility benefits and SEO benefits. SEO, I've heard directly from developers, is one way that the business has had buy in to taking a PE approach to development.

But the truth is: progressive enhancement is not part of the workflow.

What is Progressive Enhancement?

Well...it's a made up term by Steve Champeon who used it to describe the techniques he (or he and team) were using to build web sites instead of taking a graceful degradation approach.

As such, there's no one single line that defines progressive enhancement. However, Wikipedia defines it as:

[progressive enhancement] allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection

Graceful degradation works the other way around, in that the complete functionality is delivered to the browser, and edge cases and "older browsers" (not meeting the technical requirements) degrade down to a (potentially) less functionality.

The problem is based on a survey of my own followers, that's to say that they're likely to have similar interests and values when it comes to web dev, 25% of 800 developers still believe that progressive enhancement is simply making the site work without JavaScript enabled.

How do you make it work without JavaScript?

I can imagine to anyone starting out new in web development might find this question pretty daunting. First pressed with solving some complicated problem and they've finally worked out how to make it work using a marriage of StackOverflow copy & pasting and newly gained advice from books and stuff…, but now all of a sudden: make it work without the code 😱

Which explains the silver bullet response that I've heard time after time: "how would a WebRTC chat site work?" …it wouldn't.

In fact, here is The Very Clever Jake Archibald's excellent SVGOMG web site…with JavaScript turned off, watch as frustration boils over and I'm left to throw my computer out of the window…

Putting aside silly jokes, how does a web site work without JavaScript isn't really a good question. In fact, it's entirely out of context.

A better question to ask could be how do we deliver a baseline web site that's usable by the most minimal of requirements.

Very much what Jeremy Keith has said recently in response to criticism that it's impossible to progressively enhance everything with today's expectations. Progressive enhancement is:

...figuring out what is core functionality and what is an enhancement.

So how does the web community re-frame it's thinking and look at progressive enhancement as the baseline that you build upon?

Why does it matter?

Today many developers are writing "thick clients", that is, JavaScript driving a lot, if not all, of the functionality and presentation in the browser.

They do it by delivering and render views in the browser. The big upside of this is that the site is extremely fast to the user's input. The other big benefit is that there are a good number of frameworks (React, Vue, Angular, Polymer to name the "biggies" of today) that lend themselves greatly to client side MVC, i.e. full application logic in the client side code.

The problem is that the frameworks will often (try to) reinvent fundamental building blocks of a web experience. A few simple/classic examples:

  • The link isn't a link at all, which means you can't open it in a new tab, or copy it, or share it...or even click it the way you'd expect to
  • The button isn't a button
  • You can't share a link to the page you're looking at (because it's all client side rendered and doesn't have a link)
  • Screen readers can't navigate the content properly

I recently wrote about how I had failed the anchor. It pretty much touched on all the points above.

This doesn't mean this isn't possible, just that it's often forgotten. In the same way that Flash was often labelled as inaccessible. This wasn't true, it was possible to make Flash accessible, it's just that the default development path didn't include it.

A more extreme example of this was seen in Flipboard's mobile site. Importantly: mobile site. Flipboard render the entire page using a canvas element. I can't speak for the accessibility of the site, but on mobile it performs beautifully. It feels..."native". And with that, it's also broken. I can't copy links, and I can't copy text - akin to the Flash apps and even Java applet days. It looks great, but it doesn't feel "of the web".

† caveat: this was true in 2015, it's possible…likely it's been thrown away and fixed…I hope.

The problem is: browsers are pretty poor when compared to the proprietary and closed platforms they're constantly compared to.

There's pressure (from SF/Apple/who knows) to deliver web sites that feel "native" (no, I won't define this) and browsers are always playing catch up with native, proprietary platforms: this is a fact.

Native media elements, native sockets, native audio, native push notifications, native control over network - this all took it's merry time to get the browser. So when a company decides that the tried and tested approach to styling at list of articles won't give them the unique UX they want and the 60fps interaction, then of course they're going to bake up their own technology (in Flipboard's case, re-inventing wheels with canvas...the exact same way Bespin did back in it's day).

But...how would a thick-client work without JavaScript?

Angular, for instance, did not have a developer story for how to develop a site with progressive enhancement as a baseline.

Does this mean it's not possible? I don't think so. Without the stories though, developers will gravitate towards solved problems (understandably).

What does this story look like when a framework is a prerequisite of the project?

Web Components

Web Components are a hot debate topic. They could cause all kinds of mess of the web. On the other hand, they're also a perfect fit for progressive enhancement.

Take the following HTML:

<input type="text" name="creditcard" required autocomplete="cc-number">

Notice that I'm not using the pattern attribute because it's hard to match correctly to credit cards (they might have spaces between groups of numbers, or dashes, or not at all).

There's also no validation, and the first number also tells us what kind of card is being used (4 indicates a Visa card for instance).

A web component could progressively enhance the element similarly to the way the browser would natively enhance type="date" for instance.

<stripe-cc-card>
  <input type="text" name="creditcard" required autocomplete="cc-number">
</stripe-cc-card>

I wonder, are web components the future of progressive enhancement?

Potential problems on the horizon

Developers are inherently lazy. It's what makes them/us optimise our workflows and become very good at solving problems. We re-use what's known to work and tend to eke out the complex parts that we can "live without". Sadly, this can be at the cost of accessibility and progressive enhancement.

I think there's some bigger potential problems on the horizon: ES6 - esnext (i.e. the future of JavaScript).

"But progressive enhancement has nothing to do with ES-whatever..."

Taking a step back for a moment. Say we're writing an HTML only web site (no CSS or JS). But we want to use the latest most amazing native email validation:

<input type="email" required>

Simple. But...what happens if type="email" isn't supported? Well, nothing bad. The element will be a text element (and we can validate on the server). The HTML doesn't break.

JavaScript isn't quite the same, but we can code defensively, using feature detection and polyfills where appropriate.

ES6 has features that breaks this design. Syntax breaking features that cannot exist alongside our ES5 and cannot be polyfilled. It must be transpiled.

There's currently talk of smart pipelines that can deliver polyfilled code to "old" browsers and light native ES-x features to those newer browsers. Though, I would imagine the older browsers would be running on older machines and therefore wouldn't perform well with more code in the JavaScript bundles. Compared with new browsers running on new machines are probably faster and are probably more capable than their elderly peers at running lots of code. IDK, just a thought.

Syntax breaking

There's a small number of ES6 features that are syntax breaking, the "arrow function" in particular.

This means, if the arrow function is encountered by a browser that doesn't support ES6 arrows, it's cause a syntax error. If the site is following best practise and combining all their JavaScript into a single file, this means that all their JavaScript just broke (I've personally seen this on JS Bin when we used jshint which uses ES5 setters and broke IE8).

I've asked people on the TC39 group and JavaScript experts as to what the right approach here is (bear in mind this is still early days).

The answer was a mix of:

  • Use feature detection (including for syntax breaking features) and conditionally load the right script, either the ES5 or ES6
  • Transpile your ES6 to ES5 and make both available

This seems brittle and the more complexity the more likely that as time goes by, new projects will leave out the transpile part, and forget about supporting older browsers - or even newer browsers that don't ship with ES6 support (perhaps because the VM footprint is smaller and has to work in a super low powered environment).

Since JavaScript doesn't exhibit the same resilience that HTML & CSS does, so the fear is that it'll leave users who can't upgrade, faced with a broken or blank page.

Is there a workflow that solves this? Or are we forced to support two incompatible languages on the web?


Thanks for reading. As usual, it depends. In fact, that it does depend, applies to every single project I work on.


Further reading