Introducing EnhanceJS: A smarter, safer way to apply progressive enhancement
April 2020 note: Hi! Just a quick note to say that this post is pretty old, and might contain outdated advice or links. We're keeping it online, but recommend that you check newer posts to see if there's a better approach.
As we discuss in our new book, Designing with Progressive Enhancement, and in previous articles, building with progressive enhancement is essential to ensuring a usable experience for all. But how do you determine which browsers should receive the enhanced experience and which should stick with the basic experience?
What is EnhanceJS?
How does it work?
- It assigns a class named
htmlelement. (Useful for small-scale enhancements to a page)
If any single test fails, no enhancements are made, and the page is left as is: a fully functioning basic experience (provided, of course, that it was built with proper progressive enhancement techniques).
EnhanceJS then saves the browser’s pass or fail result in a cookie to prevent the framework from running through the capabilities tests at every page load. When EnhanceJS runs on subsequent pages, it first checks the cookie and then proceeds by adding enhancements (or not); if no cookie is found, it runs through the suite of tests again.
As a fallback option, the framework script appends a “toggle link” to the end of the page for users to manually switch between the basic and enhanced versions of the site. This level of user control is valuable for those occasions when a browser passes the tests and enhancements are applied, but something doesn’t work correctly.
For a demo of a site using EnhanceJS, look no further than the page you’re reading right now! Assuming you’re in a browser with cookies enabled, just scroll to the bottom of the page, where you’ll see a “View low-bandwidth version” link. Clicking the link will toggle you from the basic to the enhanced version of this page. (If you see a “view high-bandwidth version” link, you’re viewing the un-enhanced version of the page, which means either your browser did not pass the test suite, or perhaps you already clicked the toggle link).
Sweet! How do I use it?
The first step in using EnhanceJS is to grab the lastest copy of the framework and reference it in your page. (You can grab the latest copy of EnhanceJS at the project page on Github, EnhanceJS.)
Once downloaded, reference EnhanceJS in a script tag in the head of your page:
With EnhanceJS referenced, you can run the test suite by calling the
enhance function. This function accepts configurable options, such as
We’ve passed two options,
loadScripts, to specify
capable browsers. Stylesheets are dropped into the page and loaded
ensure script dependencies are loaded before they are called.
Note: When referencing files in arrays, be sure to separate each of the file path strings with a comma, and don’t add a trailing comma after the last item in an array.
In addition to the simple file path syntax shown above, the
loadScripts options offer a more advanced format of referencing
scripts and styles that allows you to set the attributes on the
script elements. Using this syntax, you can
easily specify a print-only stylesheet, for instance; just reference the
file using object notation instead, with key/value pairs to specify any
attributes you’d like. For example, the following code adds a print
stylesheet on top of our “enhancements.css”, which is sent to all media
In the example above, we’ve added a print-only stylesheet by setting the
href attribute to the stylesheet’s file path, and the
'print'—shown in bold—to ensure it will be directed to
printers. When using this syntax, you can apply any attributes you’d
Print Stylesheet Tip: We typically reference a basic CSS file on the
page from the start (
basic.css) that contains
some basic formatting such as the font family and useful text formatting
rules, and then cascade our enhanced stylesheet rules off of those basic
rules. The enhanced CSS files are referenced using the
type, so printers will only see the basic stylesheet rules which happen
to serve as a clean print stylesheet. Try printing this page to see the
To make it easier on you, EnhanceJS will automatically set some required
attributes, such as
type="text/css" for CSS
need to specify them unless you’d like to change their default values.
The only required attributes when using this syntax are
src when using
What about IE?
In the enhanced experience, you may want to direct scripts and styles to specific versions of Internet Explorer using conditional comments (while this practice is becoming less common, there are still many cases where websites direct fixes to IE). EnhanceJS provides a similar mechanism to let you specify scripts and styles that should only load in Internet Explorer by setting the ‘iecondition’ property, with either a version number like 6 or 7, or the string ‘all’ to direct it to any version.
In addition to loading styles and scripts, EnhanceJS has many other
configuration options, such as changing the toggle link’s text (it
defaults to “View high/low bandwidth version”), adding more tests to the
default suite, and even overriding the test suite with your own set of
tests. While our default test suite covers a range of basic capabilities
that modern websites need, you might include additional tests for HTML5
features like the
For the full documentation, including the list of all options and their defaults, visit the EnhanceJS project wiki.
Did we mention there’s a book on this? For complete and detailed instruction on getting the most out of EnhanceJS, we recommend grabbing a copy of our new book, Designing with Progressive Enhancement.
How do I contribute?
If you have ideas for enhancements for EnhanceJS, or have found a bug, feel free to enter it on the project website under the “Issues” tab.