Progressive Enhancement

Stay organized with collections Save and categorize content based on your preferences.

How to apply progressive enhancement strategies to websites.

Overview

Progressive enhancement is a strategy for web design that emphasizes accessibility across platforms and browsers. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing those with better bandwidth or more advanced browser software an enhanced version of the page.

Basic level of support

Pages across platforms and browsers at are expected to meet these requirements:

  • All site navigation elements and primary content must be accessible with or without JS enabled
  • Initial fall-back content available in dynamically updated containers
  • If content must rely on JS then please put a noscripttag on the page (there is a standardized snippet with translations already available

Feature detections

Where possible, use feature detections to see if a browser supports a particular feature and then conditionally provide those javascript functionalities. The Glue library has several detection utilities available. Modernizr is also a popular choice.

You can also use shims and polyfills to teach old browsers new tricks.

Forcing non-js experience

You are not expected to get full interactions and javascript support for all browsers but are expected to provide a fallback. It's strongly recommended you give the non-js, mobile experience to users that are using old browsers that aren't supported by AngularJS such as IE8 and below and old versions of Android browsers.

You can do this by adding a conditional for bootstrapping your AngularJS app and NOT using the ng-app attribute in your html.

goog.require('goog.userAgent');

angular.element(document).ready(function() {
  // Prevent angular from bootstrapping on older IE versions.
  // angular.bootstrap is used instead of ng-app on the <html>.
  // User can customize which browsers to support.
  if ((goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9)) ||
      !goog.userAgent.IE) {
      angular.bootstrap(document, ['myApp']);
  }
});

Glue also has an App Launcher module to prevent the user from having to download scripts at all if they're using an older browser.

Progressive enhanced styling

You can write js to add a class on the html element so you can target your css to fallback and enhanced modes. Our Hercules Sass framework has plans to implement this feature.

Your detection javascript which goes in the head

goog.require('goog.userAgent');

if ((goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9)) ||
    !goog.userAgent.IE) {
  document.documentElement.classList.add('app-supported');
}

Your main site javascript file which is loaded at the end of body.

myApp.module.run(function() {
  angular.element(document.documentElement)
        .removeClass('app-supported')
        .addClass('app-ready');
});

Your sass file.

// Fallback mode. Attach styles to directive classes.
.my-component {...}

// Styling applied when the browser is supported but the javascript
// is not yet ready to avoid weird FOUC issues.
.app-supported {
  .my-component {...}
}

// Enhanced mode, nested under 'app-ready' which is added to <html>
// when app is bootstrapped.
.app-ready {
  .my-component {...}
}

Examples

Here's a few pages which all degrade gracefully and provide access to all content with or without JS present.

TODO(brandstudio-devs): Add examples

References

For anyone that wants to read further on this subject...