Progressive Enhancement: What It Is, And How To Use It?

Advertisement

Progressive Enhancement is a powerful methodology that allows Web developers to concentrate on building the best possible websites while balancing the issues inherent in those websites being accessed by multiple unknown user-agents. Progressive Enhancement (PE) is the principle of starting with a rock-solid foundation and then adding enhancements to it if you know certain visiting user-agents can handle the improved experience.

PE differs from Graceful Degradation (GD) in that GD is the journey from complexity to simplicity, whereas PE is the journey from simplicity to complexity. PE is considered a better methodology than GD because it tends to cover a greater range of potential issues as a baseline. PE is the whitelist to GD’s blacklist.

That’s All Well and Good, But Why Would I Want To Use It?

Part of the appeal of PE is the strength of the end result. PE forces you to initially plan out your project as a functional system using only the most basic of Web technologies. This means that you know you’ll always have a strong foundation to fall back on as complexity is introduced to the project.

PE goes well with the principle of “Release early, release often.” By starting with a strong foundation, you are able to release projects that work and then concentrate on adding the bells and whistles at a more appropriate time.

PE projects are easier to maintain. With this focus on “first principles,” developers can concentrate on more complex sections of system interaction without worrying about the foundation.

PE is also good for your users. It gives them the security of knowing they can visit your website using any of the thousands of user-agents available to them and still interact with your content as that agent allows.

All Right, So How Do I Use It?

In practical terms, it’s easiest to break the concept of PE into different layers, each one building on the previous to improve the experience of interacting with the website.

The Layers

The first layer is clean, semantic HTML. This allows text-based, speech-based, antiquated and robotic user-agents to navigate the content of your website properly.

The second layer is CSS. This allows visual-based user-agents to display or alter the visual representation of your website’s content.

The third layer is JavaScript. This allows user-agents that are capable of using it to provide your users with enhanced usability.

A practical example

We’ll create a Progressively Enhanced list of website navigation items whose order is saved by the user. Our ultimate goal is for users to have a drag-and-drop experience that saves the menu order via AJAX. But because we’ll be reaching that end goal through the principles of PE, all user-agents should be able to interact with our list in the way most appropriate to them.

The first layer

Here we have the semantic markup of the navigation. See navigation-1.html.

<form action="save_order.php" method="post">
	    <fieldset>
	        <legend>Order of Navigation</legend>
	        <ol>
	            <li id="homepage-12">Homepage <label for="menu-id-12">Change the order for Homepage</label><input type="text" name="homepage-12" id="menu-id-12" value="1" /></li>
	            <li id="contact-23">Contact Us <label for="menu-id-23">Change the order for Contact Us</label><input type="text" name="contact-23"  id="menu-id-23" value="2" /></li>
	            <li id="about-16">About Us <label for="menu-id-16">Change the order for About Us</label><input type="text" name="about-16"  id="menu-id-16" value="3" /></li>
	            <li id="latest-14">Latest News <label for="menu-id-14">Change the order for Latest News</label><input type="text" name="latest-14"  id="menu-id-14" value="4" /></li>
	        </ol>
	    </fieldset>
	    <p><input type="submit" value="Save new order" /></p>
    </form>

The first layer of the navigation form

The navigation is laid out as an ordered list within a form so that the user can alter the order using the input boxes provided. The individual list items are given an ID that correlates to the name of the input box (for reasons that will become apparent later — for now, it does nothing but add a little weight to the markup). The labels for the input fields help the user figure out how to use the form.

Clicking “Save” will POST to the PHP page, which will determine the new order and print the results, but which could just as easily save to a database. The page is not very attractive to look at, but the important thing is that every element is in place to allow any user-agent, no matter how basic, to read and make sense of the form. Screen readers should be able to process this form easily, and keyboard navigation is functional and enabled by default.

Our save_order.php page is very simple and just echos the order of the menu items sent through in the POST.

<?php
	foreach($_POST as $menu_item=>$order) {
	    echo "The order for $menu_item is $order";
	}
    ?>

Obviously, this isn’t a production script. It simply illustrates that the procedure for processing a form should be one of the first interactions in PE.

The second layer

Now, we’ll add a CSS layer to give the form a bit of visual elegance. See navigation-2.html.

name="code">
    <style type="text/css">
        form { width: 50%; margin: 0 auto;  }
        fieldset { background: #555555; padding: 1em; }
        legend { border: 1px #513939 solid; background: #FAFAFA;}
        label { position: absolute; margin-left: -999em; }
        ol { list-style: none; position: relative; }
        body { font: 100% serif; }
        ol li { border: 1px #FFF solid; background: #FAFAFA; padding: 0.7em; }
        ol li:hover { border: 1px #513939 solid; }
        input[type='text'] { width: 2em; text-align: center; position: absolute; left: 40%; }
    </style>

The second layer of the navigation form

We took the labels out of the document flow with position: absolute and then gave them an outrageous negative margin to remove them visually while leaving them in place for screen readers (which can still read them in the original order because we’re not removing them with display: none).

We removed the numbers from the ordered list to avoid the potential confusion of having two sets of numbers for the list items.

We maintained the font size to initially be equal to whatever the user-agent has set as a preference and asked the user-agent to use its own default serif font.

We gave the individual list elements an outline and a bit of padding to see them more easily. To give the user a little more of a visual hint that the list items are movable, we also gave them a hover state that we know will be used by any user-agent that can handle it. Input boxes are neatened up a little, too, for browsers that can handle attribute selectors.

The form now looks a lot neater and is still just as functional as the first layer.

The third layer

Finally, we’ll add the JavaScript layer, which allows the user to simply drag and drop the navigation items into the desired order. We’ll use jQuery to make the process as painless as possible (both for us and our users). See navigation-3.html.

    <script type="text/javascript">
        $(document).ready(function() {
            $('input').hide();
            $('ol').sortable({items: 'li',
                update: function(event, ui) {
                    var new_order = $('ol').sortable('toArray');
                    $.each(new_order, function(i, element) {
                        $('input[name='+element+']').attr('value', i+1);
                    });
                    $.post("save_order.php", {
                        'new_order': $('form').serialize()
                    })
                }
            }); 
        });
    </script>

The third layer of the navigation form

  1. Hide the input fields because we’re providing users with a different usability experience.
  2. Make the ordered list sortable using the jQuery UI sortable plug-in.
  3. Update the new order each time the DOM changes. We’ll use the options and utility functions in jQuery and the plug-in to get the new order for the list items and to set the value of each text field to match each list item’s unique ID.
  4. Send the newly updated form to the server via POST.
  5. Parse the new_order variable that we sent via AJAX to match the values expected by the original PHP script.

Our server-level script in save_order.php needs to change very little to still work. We simply take the new AJAX posted value and parse it into the POST that the original form was looking for. This is another of the strengths of PE: by adding the basic form interactions in the first layer, it becomes much easier to add potentially complex interactions in later stages with minimal fuss.

<?php
		if(isset($_POST['new_order'])) {
		    parse_str($_POST['new_order'], $_POST);
		}
		foreach($_POST as $menu_item=>$order) {
		    echo "The order for $menu_item is $order";
		}
	?>

Now, here’s the interesting thing about this last layer: while the drag-and-drop functionality makes menu ordering more usable for many users, it actually makes it less accessible, too. Our users now have to use the mouse to reorder menu items; those who prefer keyboard shortcuts will have a frustrating experience, and blind users would find it totally unusable (even if they could drag and drop the new menu elements, they have no way of updating the new values to their screen reader).

There are a few solutions to this problem, from as complex as rewriting the sortable jQuery plug-in to be keyboard-accessible and WAI-ARIA-compliant to as simple as providing a quick link at the top of the page that allows users to turn off JavaScript and use the more accessible version we had in layer 2.

Okay, You’ve Convinced Me…

While this is a very basic example, it illustrates the power of using Progressive Enhancement in development. By clearly establishing how a system’s interactive elements are supposed to function at the most basic level, you gain a clearer understanding of the project’s requirements. Your clients will be happy with the rock-solid results, the more accurate time-frame estimates and the easier maintenance, and you will be happy knowing you’ve provided a better, stronger product that benefits more people.

Related articles

You may be interested in the following related articles:

(al)

CSS,

↑ Back to top

Sam Dwyer is an Interactive Architect from Australia who lives in the UK. Sam has been working with the Internet since 1993.

  1. 1

    Very informative Article Sam… lots and lost of information in there.. thanks for sharing!!

    I’ve always used both graceful degradation and progressive enhancement to my web applications and designs as it just felt ‘right’ – although I never knew what it was exactly called earlier!

    Developing with progressive enhancement is actually quite simple once you understand the concept and begin putting it into practice; perhaps even simpler than making candy.

    DKumar M.
    @instantshift

    0
  2. 2

    Very, Very Nice!

    0
  3. 3

    Great article. We’ll need a lot of that, specially because if Windows 7 really kicks in, people are gonna go all the way from ie 6 to ie 8 and also with CSS 3 comming along there’ll be a lot of opportunities for improvements, but it has to be a very thought out transition.

    0
  4. 4

    Honestly today is the first time I heard of the term “Progressive Enhancement”. This and “Graceful Degradation”. Sad to say because I am a web designer. But the first mention of these words came just 30 minutes ago when I saw the video of Nate Koechley: “Professional Frontend Engineering”. This is a good watch for the front end home boys.

    http://video.yahoo.com/watch/4671445/12486762

    Thank you Sam for increasing my knowledge on Web Development. Seeing this twice within and hour is probably a sign I should do more reading and research about my field.

    0
  5. 5

    You’re shitting me, right?
    This is a terrible article. Yes, what you’re saying is true but your practical example is downright outrageous. The point of semantic markup is to actually INTRODUCE SEMANTICS TO IT. Yet you have identifiers like ‘about-16′ and shit like that. You do realize IDs also work as fragment identifiers, don’t you?

    For an accurate representation of the business (although maybe a bit lengthy), see: http://video.yahoo.com/watch/4671445/12486762

    0
  6. 6

    Nice post, but isn’t that the way every developer should work ? I mean, who would ever do a jQuery script before even doing the html form ? Would you start coding your CSS before doing your html ? Maybe I don’t get it right, so could you provide the same example with the graceful degradation method ?

    0
  7. 7

    Interesting stuff, was just researching about the PE concept from Tranceding CSS by Andy Clarke. The conept was originally by Dave SheaDave Shea, called MOSe, writing:

    “The key to the method is somewhat similar to how NN4 page design developed as CSS became more prevalent — after creating a basic, functioning page in IE, you add extra functionality with these selectors.”

    Steve Champeon coined the term Progressive Enhancement.

    0
  8. 8

    Interesting article but I’m still unclear about how your approach of Progressive Enhancement differs from Graceful Degradation. Given the same scenario, wouldn’t allowing the Javascript and Ajax to degrade back to a functional form of just CSS and HTML in effect provide the same outcome?

    I do acknowledge that your approach encourages people to take more consideration about how the form would work without the JS layer but a functional JS script that is designed to be “degradable” should also do this… albeit, not all of them do!

    I guess I would like to see you compare the two approaches side by side to Illustrate the differences.

    0
  9. 9

    Hooray! Now I guess I can apply a technical industry methodology term to the web development process I’ve been utilizing for many years already! Time to put “Progressive Enhancement Pioneer since 2004″ on the ol’ resume!

    0
  10. 10

    This has been my philosophy from the beginning, I’m glad I know what to call it, now maybe my clients will be more open to it as well haha

    0
  11. 11

    I think Progressive Enhancement is the perfect way to code, especially with time constrains. If you coming to an end of a project and it has to go live you with PG you know everything works for all users, but with GD if you run short of time you might not finish degrading a form and then there is an accessibility issue.

    Plus it is easier for a client to understand how you could add javascript to improve the user experience as they can physically see it, but if you have an all singing and dancing form the client might not understand the importance that the form must work without javascript.

    0
  12. 12

    The “related articles” are better. This one is a little too short and brings (almost) nothing fresh.

    0
  13. 13

    I would have though this sort of thing standard practice among all designers. At least that what I’ve expected nothing less of from my team. Nice to see it in writing though :-)

    0
  14. 14

    Excellent article. While being vaguely aware of the concept, I’ve always designed in the basic manner of PE as a natural way of developing sites. I always start with the basic XHTML and CSS, add some JavaScript for certain levels of interactivity, and then continue progressing into more advanced additions like animation (e.g., Flash), backend database design (for ecommerce or user registration, for example), and other “bells and whistles”. This article is an excellent introduction to the concept and the example reinforces it – great work!

    0
  15. 15

    Useful article…thanks

    0
  16. 16

    If one think of this snippet as a whole project, it would be PE. And more people should defiantly think of javascript as a layer since more and more people are turning of javascript due to the risks. I would not recommend updating the result of the form on every move though, specially if this is hooked up to a database and you have a lot of visitors. You could process it on unload or something like that instead to decrease the number of requests/queries.

    0
  17. 17

    Oh lord, lets invent more useless terminology and ideas.

    One simple question: have you ever sold this idea in a website for a client? I am not talking about your own personal blog or playground-website, i am talking client website.

    There is no such thing as Progressive Enhancement, there is only Graceful Degradation, for one simple reason – you WANT to build your sites the best you can, and then implement engines that will scale them down if users do not have Flash or JS or new browsers. Even if you think about PE, you are actually thinking only about GD, because you cannot take middle point in site’s technology-tree as a reference point.

    If you PE your site, then you have reached new highest technology point, and then that point becomes relevant reference point from where everything GDs down.

    0
  18. 18

    I’ve always used these methods but I didn’t know they have a name, I didn’t even think of them as methods, I just found it as a natural way to go about things. Thanks for the useful info.

    0
  19. 19

    Nice concept. Would it be advisable to split the CSS into two layers? One layer to make sure it works in internet explorer 6 and then another layer to add the CSS3 rules that work in modern browsers?

    0
  20. 20

    Excellent article Sam!

    I spend hours trying to explain PE to clients for them to only turn around and say “But doesnt everyone have JavaScript, why should i care if those without JS cannot use it?” – which really isnt the point im trying to get across to them.

    The point is, if you do it right from the start, then enhancements can be made to the user experience through PE… You would be suprised how many developers do not get that. Many developers see only the end product and do not care how they get there ;)

    0
  21. 21

    Nice article. Kinda ugly example, though, and the PHP is just bad, even for a non-production page.

    0
  22. 22

    What about keyboard or screenreader users?

    0
  23. 23

    I’ve always termed what I’ve been doing as graceful degradation, but I’ve been doing it as you describe with progressive enhancement. I’m not sure the two are so different – maybe the articles angle of “this is better than graceful degradation” has misled a few people out there judging by the comments.

    In my experience, graceful degradation is the same journey from simple to complex.

    0
  24. 24

    This is exactly like “graceful degradation” but using a “glass in half full” reasoning.

    0
  25. 25

    @Dingo: the difference is that with Progressive Enhancement, you are building from the ground up – build the page/form/whatever at the most basic level (usually HTML) so that it will work for all users. Then add layers of complexity to ‘enhance’ the experience of those who have better technology. This is in opposition to Graceful Degradation where one makes a site to operate in the optimal situation, and then hacking or adding to it to address users with lesser capabilities.

    Essentially, think about creating a page where if someone has CSS, JavaScript and Flash disabled – if the page has proper Hn tags, paragraph tags, valid code, etc., it might not look nice but they can read it – and so can screen readers, mobile phones, and a host of other things that can possibly only handle the least common denominator. By successively adding CSS for styling, positioning, etc., you can make the page better visually, enhance the UX with placement and emphasis, etc. for users who have CSS turned on – but you haven’t affected previous users at all.

    Follow that with adding scripts and/or Flash to further add or improve functionality, such as allowing the user to drag-and-drop instead of type, see expanded content without having to go to another page. Again, users with better browsers (JavaScript enabled, latest Flash version, etc.) get a further enhanced experience, while ‘lesser-equipped’ users are (theoretically) not affected at all. They aren’t getting the optimum experience, perhaps, but they can still accomplish the tasks they need to, though not as quickly as the enhanced users.

    @Daemon: no, there is a distinct difference. It’s a lot harder to make a site and functionality backwards-compatible, because you end up adding code on top of code to ‘fix’ what isn’t working – and in the process often add additional problems. With PE, code is added to improve experience, not fix a bad one – at its core, a PE site should work for almost anyone but give a better, faster, easier experience as users employ better resources (i.e. real browsers instead of IE6, etc.).

    One other added benefit of PE vs. GD is accessibility. In most cases, a working (X)HTML site that validates will solve nearly all accessibility issues — including screen readers, keyboard use, etc. Granted, sometimes the ‘enhanced’ functionality will be unavailable to them, but the goal isn’t to make the site equally usable to everyone – it’s to make sure that it is USABLE by everyone, period.

    0
  26. 26

    The only suggestion I really have is, and this is strictly my own opinion, that it seems silly to remove the input boxes in the final layer. Sure, you’re providing users with a different experience, but you should also find a way to convey the possibility of that form of interaction without eliminating another one. Some people may want to drag them around, and others might want to put numbers in boxes. When the overhead for that is minimal (in fact, it’s extra work for you to remove the input boxes), you should really just support multiple interaction styles.

    After all, the web isn’t about railroading your users (some will disagree), it’s about helping them do what they want in the most natural way they can.

    0
  27. 27

    It’s funny that this type of thinking is covered more…and that “old hats” are being used more and more in the “new” technology of the internet. This really is simply basic project management. You lay out the project strategically and then for the most part build the foundation and build out from there.

    I am happy to see articles like this…everyone should learn this, whether in web design or any other field. The strategy is the same really, just tweak it.

    I am TRYING not to put anyone down, but anyone building sites (no matter what stage you are in) needs to know this principle…however you want to term it. (I know we al need a little nudge)…but there is so much more to design than simply making it pretty and “enhancing the user experience”:

    Make it work…well. (period) If it works well (your foundation), then usually in my experience, the look, feel, etc…naturally (with a lot of work of course) shine through…form fits function and all that.

    0
  28. 28

    Binary.Coded.Brain

    May 1, 2009 5:07 am

    Great article!
    For my university degree project I’ve used Progressive Enhancement but with a complex link system. JavaScript Handlers anchored on _a_ tags that transforms the link _href_ in Ajax powered functions that call page (_div_) update. PHP gui layer able to understand the doubled presentation method and respond with the requested _div_ content.
    Concluding, with JS enabled all the system works with Ajax, otherwise the system use the common “click/refresh” interaction.

    0
  29. 29

    Fantastic article! Although I am surprised by the number of comments by people who seem to have completely missed the point (I’m looking at you Daemon – see Marty’s comments).

    @Andy – I think the assumption is that the semantic ids match up to associated database ids for use in the php.

    C’mon people, its not rocket surgery.

    0
  30. 30

    I simply want users to order three graphic images in a vertical row by preference 1, 2 and 3 using any form of client side javascript like jscript, bake a preference cookie of their ordering and pass it to my server, so readers can be fed the appropriate ads according to the order they stacked the pictures by interest.

    Is there an easy way to do this? How do I search for it? Everything I find is very theoretical and not easily adaptable for a beginner. Any help, anyone?

    0
  31. 31

    This actually helped me out alot, as a current web design student I didnt realize that I was using PE. As far as the three steps go I see how that can go from using a mobile device to a desktop or laptop.

    0
  32. 32

    such a stupid concept. Really? people make things harder than they really should be.

    0
  33. 33

    Hi,There is a problem from the last utpade 0.7.1.0:I usually keep the status bar (add-on bar) hide, but from this utpade it reappears every time a new window is open or Firefox restart.Also open in tab has a issue to, I fix it from about:config modifyheaders.config.openNewTab=trueCheers!

    0

↑ Back to top