Best Practices for Progressive Enhancement in Web Design

The craft of building websites is incredibly complex with many fast-changing parts. The goal of the web design community is to lessen the complexity, and reduce the potential for error at each stage of the creation process.

Progressive enhancement is such an idea in web design that aims to reduce errors and provide a consistent user experience across the board. The concept has its own Wikipedia page which explains it as a method of fully-accessible content, rendering enhanced features only when supported by the browser.

It’s easy to understand progressive enhancement but not as easy to apply it directly to your design work. I’d like to cover some best practices for progressive enhancement in real-world projects to help designers think more sustainably about their workflow.

1. Understanding Progressive Enhancement

The theory of progressive enhancement recommends to start with a simple website that works in all browsers, making it accessible for every visitor. Then add features whenever possible.

This is the opposite of graceful degradation which includes all features by default, then degrades when something doesn’t work.

Progressive enhancement is better for the overall user experience, because at its core it loads only necessary elements. Every web browser can support text (and usually images). Without any CSS this information will look bland and tasteless, but it’ll be accessible.

This List Apart article argues that progressive enhancement is content-first with styles and dynamic components added later. Content in semantic HTML should be delivered before anything else.

The advanced CSS and JavaScript we use today are widely supported, but if we want to follow the principles of progressive enhancement, they should be considered luxuries.

Here’s a general rundown of the main features of progressive enhancement that you should take into account:

  • Semantic markup for all content
  • Users’ browser preferences needs to be respected
  • Content and basic functionality should be available to all users
  • Unobtrusive JavaScript is loaded only in environments that can support it

Technological restraints in front-end development are primarily determined by browser compatibility. Progressive enhancement gets you back to the basics, thinking about how the bare-bone simplest webpage might look like. From there, you can plan for more advanced features, like CSS3 properties.

But what about browsers that don’t support modern CSS3? This is where sites like Can I Use come into play. You should decide which features are worth implementing and make judgments based on the target audience of your website.

2. Subsistence In Stylesheets

Most browsers today support all the basic properties you need. But advanced CSS3 is still a problem for legacy users, and progressive enhancement offers a solution.

Instead of looking for fallback methods to maintain these new features, concern yourself first with proper layout structures.

Write semantic HTML and CSS markup that works in as many active browsers as possible (support for ancient browsers like IE5 support isn’t necessary).

jsfiddle columns css example

Take for example this JSFiddle that uses floats with two sidebars (.fixed), and a fluid content area (.fluid). If you delete all CSS, and rerun the code you’ll notice everything stacks up nicely with the first column, then second, and finally the last.

jsfiddle no css columns

Some developers would prefer to have the content column (.fluid) appear first in the HTML. This is where progressive enhancement comes into play, and alternate CSS solutions become viable.

The two primary goals of your HTML are as follows:

  • Fully semantic and valid code
  • A consistent experience for everyone

The most straightforward way to achieve these goals is to start from nothing and work up, as most progressive enhancement advocates would recommend it.

If your code looks good with CSS both disabled and enabled, then it offers a reasonable solution for everyone.

It’s also worth considering at what point you drop support for something. Microsoft has already dropped major support for IE6 , so users running that browser may not be worth your time.

But there’s still one big question: if a browser doesn’t support my modern CSS, what should I do?

You simply write code that works without it, and consider the modern CSS as a progressive enhancement. This is the beauty of the progressive enhancement methodology.

You don’t need fallbacks, because you’re basically assuming that nothing is supported by default.

Progressive enhancement methods are about making the site usable even in cases when something isn’t supported—but if it is supported, all the better.

You need to consider how content actually flows without CSS. For example, when I disable CSS on Transmit’s website, the content still flows organically down the page.

transmit website css disabled
IMAGE: Transmit

Yes, it’s ugly, and yes, it feels like we’ve lost twenty years of progress… but it works.

3. Handling JavaScript

It’s worth mentioning that each JavaScript issue you may bump into during the development process is tricky and unique. When you build a new project with progressive enhancement, you should list all your required JS-based features, and consider how they could operate without JavaScript.

This will require lots of online research to find valid solutions. Aaron Gustafson wrote a great blog post with solutions to various problems, like replacing Ajax with a meta refresh for content inside an iframe.

Also, when you create JavaScript tabs, it’s a good idea to use anchor links with real ID values. That way, when JavaScript is disabled, you can still have the tabs visible and accessible by anchor value. Aaron wrote another piece on A List Apart that covers a more general overview of how you should think about these problems.

Here’s another example. Let’s say you have a link that loads content dynamically. The href value is empty, because everything loads via JavaScript with the preventDefault() method.

Instead, it would be wise to set the href property to point to a different page where the content could load naturally, but the visitor only sees that page when JavaScript is disabled.

Progressive enhancement is about more than JavaScript, but with web development advancing further every year, there’s no doubt that JavaScript plays a significant role.

Operate under the assumption that everything has been disabled, and scale up from there. This might include problems with embedded widgets that are out of your control, the <noscript> tag is a viable solution here.

Also think about JavaScript features that lack comprehensive browser support. This includes the fetch API, the push API, the arrow function syntax, or even browsers without support for modern libraries like jQuery.

Every feature requires individual testing with an individual solution.

The essence of progressively enhanced JavaScript is to build content that functions without any scripting. This may lead to a rudimentary user experience, but that’s okay as long as the website is usable, and the content is accessible.

If you want to do live testing, you can typically disable CSS and JavaScript in every major browser to see how your website performs. It’s also worth considering using extensions like A-Tester for WCAG compliance.

JavaScript with progressive enhancement is a huge topic. Here are some posts to help you dig deeper:

Where Progressive Enhancement Falls Short

Although progressive enhancement is a brilliant idea for almost every type of modern website, it simply may not be applicable to projects that aim to push the limits of web technology.

For example, this methodology is not a good solution for web applications that function solely on Ajax calls. Is that a good choice for accessibility? No, of course not. But if that were the case most of Codrops’ tutorials wouldn’t even exist. You have to remember the target audience.

A business website probably doesn’t have the audience that cares about flashy new CSS3 perspective properties, but web developers can be the perfect audience for such advanced features.

Progressive enhancement only falls short for web applications that simply don’t care about going back in time. I realize these web applications are few and far between, but developers love progress, and in some cases it can be sensible to forge ahead with new tech leaving the stragglers behind.

I am a proponent of progressive enhancement (or even graceful degradation, your choice) for general web projects. But I also realize it’s not the perfect solution for everything. In fact, there is no perfect solution. It all boils down to audience needs and project goals.

Further Reading

If you’re constantly building web projects, you should consider applying progressive enhancement to your workflow. It’s much easier than it seems at first glance, and it all starts with the fundamentals. Most topics surrounding progressive enhancement just require practice and testing. Try out the suggestions from this article, and see what works best for your workflow.

If you want to learn more about progressive enhancement, check out these related posts: