Categories
HTML5 Specs

Is the Progress element truly progressive?

One of the new HTML5 elements is the progress element. It’s an element that allows the web page developer to provide minimum, maximum, and current value attributes, and the browsers update the appearance accordingly. If the value attribute isn’t present, the progress element is considered an indeterminate progress element. In other words, a throbber, such as this example, created using one of the many online throbber generators.

The default appearance of the element is a long bar, with the current value represented in some way. The browsers provide a default appearance based on the following directive:

When the progress binding applies to a progress element, the element is expected to render as an ‘inline-block’ box with a ‘height’ of ‘1em’ and a ‘width’ of ’10em’, a ‘vertical-align’ of ‘-0.2em’, and with its contents depicting a horizontal progress bar, with the start on the right and the end on the left if the ‘direction’ property on this element has a computed value of ‘rtl’, and with the start on the left and the end on the right otherwise.

User agents are expected to use a presentation consistent with platform conventions for progress bars. In particular, user agents are expected to use different presentations for determinate and indeterminate progress bars. User agents are also expected to vary the presentation based on the dimensions of the element.

For example, on some platforms for showing indeterminate progress there is an asynchronous progress indicator with square dimensions, which could be used when the element is square, and an indeterminate progress bar, which could be used when the element is wide.

Requirements for how to determine if the progress bar is determinate or indeterminate, and what progress a determinate progress bar is to show, are included in the definition of the progress element.

You’ll probably have some ability to change some visual aspects of the progress bar, but doing so will probably require that you use a combination of browser-specific CSS property values: -o-progress-fill, -webkit-progressbar-fill, and so on.

One of the reasons given for the progress element is that it is more semantically meaningful than using existing web page elements (typically a div element nested within another). As with the details element, this is another case of attaching semantics to a behavior, when what is semantically meaningful is the overall event taking place. When I brought up the fact that there is no way to associate the progress element with a specific element and action, the HTML5 editor made the progress element into a form element, of all things, so that we could then attach a form label. However, rather than make the element more meaningful, all that’s been accomplished by this change is to make the element that much more kludgy. Case in point: what happens if the progress element is actually added to a form? Is its current value sent with other form element values to the server application?

Accessibility folk seem to like the element because of its supposed built-in semantics. In the ARIA mapping table in the HTML5 specification, the element is mapped to ARIA values: the element’s role is progressbar, the minimum value attribute is mapped to aria-valuemin, the maximum value to aria-valuemax, and the current value to aria-valuenow. What is not happening, though, is that the action that’s taking place is not associated with the progress; just providing a label for the progress element is not sufficient.

I created a very simple progress bar example that updates the progress bar each time a button is clicked. The region related to the progress element is another div element that is updated to reflect the progress value. It could easily be a canvas or SVG element where a complex graphical operation is being performed that could take a considerable amount of time, or a long Ajax query or update.

I mapped the impacted region and the progress element using the aria-describedby attribute, and I note that the region is “busy” using the aria-busy attribute.

The progress indicator in the example is just a simple div element nested within another. As the action “progresses” (the button is clicked), the progress is noted, both visually and via setting ARIA attributes on the element. When the progress is complete (100%) the aria-busy attribute on the active region is set to false. Since I’m using the progressbar role, when the page loads in IE8 or Firefox 3.6 in Windows using the open source NVDA screen reader, an audio cue is provided in addition to the visual cue as the progress bar progresses.

The same visual and audio cues should also happen with the built-in progress element, supposedly with less need for code. However, as the example demonstrates, only two lines of code are necessary in order to manage the visual appearance of the bar—all the rest of the code should be the same regardless of approach:

var bar = document.getElementById("bar");
  var action = document.getElementById("actionhere");
  var progress = parseFloat(bar.getAttribute("aria-valuenow"));
  if (progress >= 100) {
    return;
  }
  progress+=10;
  bar.setAttribute("aria-valuenow",progress);

  // following two lines of code are what's necessary to implement
  // the visual display
  var width = progress * 4 + "px";
  bar.setAttribute("style","width: " + width);

  // a little extra
  action.getElementsByTagName("p")[0].textContent = "Action is " + 
                 progress + "% complete";
  bar.innerHTML = progress + "%"; 
  if (progress == 100) action.setAttribute("aria-busy","false");

So, you say to yourself: six of one, half dozen of the other. If the code difference is so small, then it doesn’t matter which you use. However, you would be wrong with this assumption, and the reason why is the very semantics the progress element supposedly provides.

In the example page, I have an action region associated with the progress element. I need to associate the two with additional ARIA attributes. The implication with the progress element is that no other modification to the application is necessary in order to provide an accessible solution. However, the progress element by itself is not semantic—it is the progress in association with the impacted page region and action that is semantically interesting. The progress element is nothing more than a visual indicator.

True, people could still use the additional ARIA attributes to make the necessary associations whether you use the built-in progress element or a simple custom widget, like my example. However, the implication has been with the progress element that no additional ARIA or other markup is necessary in order to form a complete semantic behavior. This isn’t true, but that is the impression given: by using a built-in element all the accessibility requirements are met.

This assumption about the superiority of built-in versus “bolt on” traces back to a decision about philosophical direction made years ago: providing built-in elements over library-enabled alternatives is the preferable approach, because web developers and designers don’t have to do anything special in order to make a page accessible. No offense to the many good people relying on this approach, this assumption falls short of reality. Regardless of how many of these elements become built-in—and the web space could become mighty cluttered if we try to create every possible variation of built-in element—you can’t bypass involving the web page author/designer/developer when it comes to making a page accessible. You have to engage people and provide the necessary tools and clear, unambiguous instruction regardless of how many elements get built-in. You can’t hope to make a page completely accessible by making an end run around the web community.

The progress element only provides part of the accessible solution, and frankly, the least important part of the solution. It is the association between the visual/audio indicator and the action and the page element(s) that’s really important, especially if the action makes the page unresponsive for a period of time.

Let’s say you have a HTML table with a set of values and you want to perform various calculations on those values, and have the results displayed. If the computations are complex, it may take some time to display the values and you want to provide some indicator that something is happening. You could overlay the page and display a throbber animated GIF, which is common now. This works, but if you can track the progress of the application, then you’ll want to provide some indicator of how far along the process is.

Providing a progress element and a label doesn’t hack it. You need to associate the action with the indicator, and you need to do so in such a way that everyone knows that this is the application progress for that element/action pair.

You may also want to take additional actions. If the element behavior results from an action on the part of the user, you’ll want to stop them from doing the action again until the current action is finished. This, too, is part of the “semantics” associated with the behavior. You can even pair semantic rendering with behavior and appearance, by pairing CSS settings with the region’s aria-busy value.

Again, there is nothing stopping you from using the progress element with this type of behavior, but using the element doesn’t suddenly make this all more simple. On the contrary, what the progress element provides is actually the simplest part of this combined element/behavior semantic.

There is also an associated cost for this new element: yet another element for HTML authoring and WYSIWYG tools to implement; for form generation tool developers to have to incorporate (since it is a “form” element); for designers and developers to have to figure out how to use, or style. Styling of the element is a particular issue, because each browser vendor will provide its own default styling, which we may, or may not, be able to override. Whatever we’re given, though, can’t hope to match the various and sophisticated JavaScript/CSS enabled progress bars we use in our applications today.

What happens, too, while we wait for progress to be implemented in our target browsers? Unlike the input fields, there is no “fallback” behavior for this new form element. We could give it a style and set its width, just like we do with the div element, but what happens when the progress element is implemented in some browsers, but not in others? Setting the width would set the width for the element, not the bar value amount, so we’d have an ever expanding bar of which a certain percentage is filled in. To work around this problem, we have to build in tests to see if the progress element is supported or not and perform whatever functionality based on the test—making the element that much more difficult to support. In reality, too difficult to be appealing to a lot of developers, especially those using framework libraries such as YUI or jQuery, where the developer can implement a progress bar with one line of code, and be able to style and design the progress bar however they want.

The progress element just doesn’t add anything new or interesting to provide an incentive to use. We can just as easily create an accessible version with what we have now, without having to incorporate functionality to test for element support, or wait for older browsers to fall into disuse. The use of the element isn’t, by itself, overly accessible, since it only provides part of the overall semantics. More importantly, it ignores the progress we’ve made when it comes to framework libraries and dynamic applications. Most of the major UI libraries already have ARIA built into the existing progress bar widgets, and are prettier and much more interesting: the jQuery progress bar is accessible, easy to use, and themable; the YUI progress bar can be customized; other libraries provide even more packaged behaviors. We’d be better spending time providing tutorials on how people can use these libraries, accessibly and semantically, then to push the use of an element that’s not very useful and is dated even before it hits the street.