Menu Search
Jump to the content X X
Smashing Conf New York

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

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

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? Link

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? Link

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 Link

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 Link

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.html1.

<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.html2.

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.html3.

    <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… Link

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.

You may be interested in the following related articles:

  • Graceful degradation versus progressive enhancement
  • Delivering the right experience to the right device
  • Pragmatic progressive enhancement – why you should bother with it

(al)

Footnotes Link

  1. 1 https://www.smashingmagazine.com/images/progressive-enhancement/navigation-1.html
  2. 2 https://www.smashingmagazine.com/images/progressive-enhancement/navigation-2.html
  3. 3 https://www.smashingmagazine.com/images/progressive-enhancement/navigation-3.html
SmashingConf New York

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

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

  1. 1

    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
  2. 2

    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.

    3
  3. 3

    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!

    -1
  4. 4

    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
  5. 5

    Very, Very Nice!

    0
  6. 6

    Diogo Terror

    April 22, 2009 2:24 pm

    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
  7. 7

    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
  8. 8

    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
  9. 9

    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
  10. 10

    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
  11. 11

    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
  12. 12

    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
  13. 13

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

    0
  14. 14

    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
  15. 15

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

    2
  16. 16

    Useful article…thanks

    0
  17. 17

    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
  18. 18

    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
  19. 19

    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
  20. 20

    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

↑ Back to top