Progressive Enhancement - Don't Jump Into the River Without Testing the Depth First

Christian Heilman | August 4, 2010


Web development is still more like wild, wild web development. Innovation happens by pushing the boundaries of technologies and hacking and playing around with systems until we find a way to make things work we want them to. A wide range of systems our code will run on and the lack of support for web technologies across different browsers make being a web developer a daunting task.

A lot of times we find ourselves giving up and categorically demanding that our end users need a certain environment to see our products rather than dealing with the differences and writing solutions that are elegant and flexible enough to adapt to different setups.

The web is for everyone

This is sad, as the web was always meant to be an open platform that caters to the needs of the end user. If I buy a newspaper I have to go to the corner shop or pick it up from my mailbox. I need then to find a place to spread it out to read it and if the font is too small for my needs I need to use a magnifier.

With news on the web I don't have that much trouble - I can read them on any device I want to (my mobile, TV set, laptop, notebook, tablet PC... ) right from the comfort of my home and I can cater them to my needs. As a blind person I would have to OCR scan a newspaper to read it or order it in Braille or large print or any other special format. On the web a screen reader tells me what is going on and if the font is too small I can resize it with my browser.

This is amazing and it is the single most important thing of the internet as a medium - it should make our lives easier. All that should be required of us is to have electricity and some software that speaks HTTP, pulls data off the web and converts it to something I can enjoy - be it text, audio, video or a game to play.

Limiting the range by design

The sad part is that we forgot about this some time ago and instead we plan our projects with a very limited scope in terms of technology - we predefine screen sizes, we use technology without falling back to something useful when it isn't available and we hope all will work out.

We also are blissfully unaware of the problems we cause with this - as people on the web don't complain but instead just don't come any more. This is especially the case with people with disabilities.

In my years working in the accessibility world I encountered a lot of people getting stuck because of minor oversights of web site maintainers. At the same time I did not encounter many people complaining. Instead of trying to find a flaw in our products they just gave up and blamed themselves for not being clever enough to use a computer. This is very annoying as the web should empower people and increase communication - not build a special world for people who can afford it and are healthy enough to consume it. By leaving the physical space we are making our products much more versatile - by limiting our designs to arbitrary measurements and environments we forfeit this opportunity.

Given the nature of the internet and the constant flux of changing technologies it is about time to realize one simple truth about web development:

There is no status quo - what you think is hot and cool right now will be outdated and embarrassingly bad a few months down the line.

And this is where we get to the gist of this article: if you want to build working, scalable and maintainable solutions for the web you want to think about progressive enhancement of your products.

What is Progressive Enhancement?

Progressive Enhancement is a methodology and a concept of IT development. In its most basic form it falls down to a few steps to think about:

  • Check if the current environment has support for a certain technology
  • If it does, apply that technology to make the product better

There is no magic to this and a lot of people ranting about Progressive Enhancement holding us back in our creativity have no understanding of the subject. It is not about supporting Internet Explorer 6, it is not about JavaScript fallbacks that mean double maintenance - it is about not building things that are bound to break.

New hardware to support

This becomes increasingly important when you look at the changing environment we roll our products out into: people consume the web on Desktops but more and more on mobile devices and a lot of them have touch interfaces rather than a mouse. If your solutions rely on hover effects and use tiny elements with not much space in between them they can be terribly frustrating to use on a Google Nexus, iPhone or iPad. Instead of building systems that cater for both scenarios people start building the same application 5 times for different environments. This is a maintenance nightmare and whilst it allows you to cater for certain specialist systems it also means that you spend five times the amount of time building one solution. Software is clever enough to make sure you don't need to build the same thing several times - if you use it cleverly.

Progressive Enhancement is about separation of concerns

Instead of starting with how the product should look and behave like you cover a few simple questions:

  • Where does the data come from?
  • What is the main task that people will need to fulfill?
  • How can we make this the easiest?
  • What is very likely to change in the future?
  • What can go wrong and how to avoid the most obvious hiccups?

There are all kinds of different ways you can handle this and the approach differs from technology to technology and use case to use case. The basic questions, however, stay the same.

A few examples

Let's take a look at a few examples of the progressive enhancement approach.

UK House Prices

When the UK government decided to release free data to the world, I was asked to build something with that information. I had a day to build something that would be shown to the press. I took a dataset that contained the house prices in the UK over the years and turned it into an interactive interface using the Autocomplete interaction pattern for the selection of the city and a slider control to choose the time frame:

When JavaScript is not available or a browser that doesn't support the technology is in use, the Autocomplete and the slider fall back to dropdown menus.

When you select a time frame you get an interactive bar chart with the information and house offers from the area:

This bar chart system was a bit of a challenge and if you look at it you probably will not immediately see what it is. If you turn off CSS (or look at it with a Blackberry phone) you will see though that it is a pure CSS solution:

So you see that the solution changes according to the support of the device and that is Progressive Enhancement. The way I achieved this is by totally separating the data from the interface. The first thing I wrote was a PHP script that retrieves the data and converts it into HTML based on various parameters.

If you click this demo link you will see what that looks like:

All I needed to do then is write the HTML form to allow the user to enter the different values, call the API when the form was submitted and include the API in the main document. When JavaScript was available I overrode the form submission functionality and instead printed out the HTML with JavaScript.

This gave me a few options I would not have had if I had started with the JavaScript:

  • I released the CSS bar chart solution and API as an extra bit of software (The CSS bar charts source code is here) and thus both spread the love and advertised the web site to developers.
  • I support any environment as the dropdowns only get replaced with the Autocomplete and the Slider when the browser supports it (both these solutions were actually copied from the example pages for the YUI Autocomplete and YUI Slider and just slightly modified).
  • I could release the API running the system as an open API or make it part of YQL to have a webservice that is cached for me
  • I had time to add a dash of design (granted, not my forte) to it and still stayed in the 24 hour period

As it took me only a short while to create the app using the progressive enhancement approach I had enough time to also convert it into an app for the Yahoo homepage by changing only a few lines of code:

Note: you might realize that the solution right now doesn't work on a touch interface (at least on my Nexus). I will fix this soon once I get another device for testing. The good news is that for me the fix will be as easy as detecting the device and not applying the JavaScript. Had I written a non-progressively enhanced solution this would mean a complete re-write.

Another example of the power of this approach is the following little tool.

Flickr collector

I currently write a lot of presentations and I like to use imagery in those and also in blog posts to liven them up a little. Instead of having to pay for these images I use Flickr to look for pictures released under a Creative Commons license which makes it OK for me to use them.

I found, however, that the Flickr interface can be a bit daunting to find the photos and subsequently get the HTML to display these photos. This is why I build Flickrcollector for myself:

You can get the Flickr collector source code on GitHub

As you can see when you play with it, Flickr collector allows me to search for a certain term and get photos from Flickr. I can click each of the thumbnails and see the information of the photo and get the HTML code ready for copying and pasting. If the browser allows it (meaning that it supports JavaScript) I can also drag and drop thumbnails into a collection container on the bottom of the screen or remove them by dragging them to the wastebasket on the bottom right. Once I am happy with my collection, I can hit a button and get the HTML for all the images.

Without JavaScript I only get the search and display functionality and I miss out on the collecting part of the application. However, if you turn off JavaScript (or try it on a Blackberry) you will see that actually I won't miss the functionality but instead I don't even hear about it:

As you can see not only does the functionality change, but also the description. This is one very important feature of progressive enhancement - never offer something that might not work and also don't tell people that it should be there. In this case the fully featured app has the following intro:

Flickr collector is a simple interface to collect photos from Flickr and copy and paste the HTML to embed them into web sites. Click any of the photos below to see its details. Below the photo you will get the HTML code to copy and paste. You can drag photos into the collection below the thumbnails and remove them from the bin by dragging them into the removal box. Once you are done, hit the "See all code" button to get the HTML of all the photos in your collection box.

If there is no JavaScript available, the following is displayed:

Flickr collector is a simple interface to collect photos from Flickr and copy and paste the HTML to embed them into web sites. Click any of the photos below to see its details. Below the photo you will get the HTML code to copy and paste.

This should be pretty basic but a lot of people forget this - a properly enhanced application needs support from copy, design and development. It is not a drop-in feature.

The practical upshots of progressive enhancement:

All in all I hope these explanations and the conclusions from the examples showed that there are many benefits to applying progressive enhancement:

  • It forces you to architect your solutions, not just design and build them - you consider several layers of functionality (data, display, outbound delivery via an API) that each can live on their own and can be replaced if the need occurs instead of creating a single, monolithic system that is much harder to maintain.
  • As you architect your solution you also cut it up into much more sizeable chunks you can develop quicker and you can confidently make time estimates for. If you build one big system from a design towards the solution your time estimates will always be way off.
  • As you are testing whilst developing and you build sensible, working solutions and enhance them as you go along you will always ship working software. If you run out of budget and time you still have something online that works and can be improved later.
  • As you create a solution that clearly separates the backend and the frontend of your application you can change each of them in the future without having to touch the other.
  • As you separate the skills you can work in parallel - all you need to agree on between backend and frontend engineering is the data coming back from the API and how to access it.
  • This also simplifies maintenance - you know for a fact that all the data related information comes from the backend via the API - which means you know where to debug when there are display issues that are not the fault of the HTML/CSS guy
  • Your testing time is reduced drastically - as environment that cannot support a certain technology will not be bothered by it there are no bugs to fix in them.
  • You don't frustrate end users. There is nothing more annoying than some functionality being promised to you and then not working. As you even enhance your copy this will never be the case.


About the Author

Christian Heilmann grew up in Germany and, after a year working for the red cross, spent a year as a radio producer. From 1997 onwards he worked for several agencies in Munich as a web developer. In 2000 he moved to the States to work for Etoys and, after the .com crash, he moved to the UK where he lead the web development department at Agilisys. In April 2006 he joined Yahoo! UK as a web developer and moved on to be the Lead Developer Evangelist for the Yahoo Developer Network. In December 2010 he moved on to Mozilla as Principal Developer Evangelist for HTML5 and the Open Web. He publishes an almost daily blog at and runs an article repository at He also authored Beginning JavaScript with DOM Scripting and Ajax: From Novice to Professional.

Find Christian on: