Categories
HTML5 Specs

Progress Element: what I’ve found

To recap my weekend effort with the WebKit nightly implementation of the HTML5 progress element:

  • I created a application that uses the progress element and provides a text-based fallback for the element. You need to use setAttribute and getAttribute to get the progress element’s value attribute, as accessing the attribute directly on the object only works when progress is implemented in the browser. Apple’s VoiceOver seems to only audibly announce the state of the progress bar when it first receives focus. I can’t test with Firefox and NVDA on Windows, as Firefox has not yet implemented the element.
  • I created another application that provides a graphical progress bar fallback using two div elements. I also use ARIA to provide audible signals of progress bar state. During this experimentation, I found that you can’t change the background-color of the progress element, as this will wipe out the progress effect.
  • I created a third application, this time embedding the graphical progress bar fallback directly in the progress element. This approach works, but is invalid, since the progress element does not allow flow content. The assumption we take from the allowable content is that we’re supposed to accept a text-only progress bar fallback. This assumption of text-only fallback completely disregards the state of the art when it comes to progress bars that exists today.
  • I created a indeterminate progress bar application today. I discovered that you can’t change height or width of the progress element after all. If you do change the progress bar’s style setting, it adversely impacts on the indeterminate progress bar display. You have to accept the exact presentation of the progress bar, as determined by the browser. Frankly, I’ve never been overfond of the “blue gel” progress bar for Apple, and I think the progress bars, as implemented in WebKit, are ugly. Again, the indeterminate progress bar completely ignores the state of the art of “throbbers” that exists today. Can you see using this progress bar in Twitter?

I would move on to testing other new HTML5 elements, except for one small problem: the majority of new HTML5 elements have no real world implementation. Even many of the input elements, which have been around for six years have no implementation, or only partial implementation in one user agent, Opera.

As I wrote in an email to the HTML WG:

There are many new and modified elements in the HTML5 specification that do not have any implementation, and several that only have partial implementation by one User Agent. There are no implementations of any of the new or modified elements by any User Agent other than browsers (such as in authoring tools, or WYSIWYG plug-ins). Lack of implementation, or plans for implementation, especially when an element has been part of the WD for years, seems to meet the criteria for “features at risk”. Features at risk are those most likely to be challenged during Last Call, which could impede progress of the document through the Last Call process.

We get so caught up in the gee whiz newness of HTML5, and all its perceived glamor and sexy techiness that we forget that, for all intents and purposes, three-quarters of the specification is untried.

Categories
HTML5 Specs

Cross-browser implementation of the progress element

A useful coincidence: just after I wrote my concerns about the progress element, the WebKit nightly contains the first implementation of this element.

I created an application to test the element. It works as I expected, and is somewhat accessible, though Mac’s VoiceOver would only voice the progress when the element first receives focus. Note, support for the element is only in Webkit nightly on the Mac.

I created a cross-browser version of the application that should work in most modern browsers—modern meaning IE8, not IE5.5, IE6, or even IE7. I had a heck of a time with the application.

The first challenge was the fact that IE8 doesn’t allow dynamic styling of the progress element, even if you use an HTML5 shim. What was more surprising was that Webkit on the PC and Chrome had problems with the progress element, period. Both kept giving me errors about a progress element within a div element, and neither would allow any form of dynamic access.

If you try to emulate the progress element’s effect, using the actual progress element in browsers that don’t currently support the element, setting the background-color for the element wipes out the progress effect with the Webkit nightly. Other than setting width and height, you can’t style the element. Or at least, I’m not sure how to style the element using general CSS properties.

I had to create a separate div element for those browsers that don’t implement progress. To make it work, I tested for progress element support, and if the browser does not support the element, turn off its display and turn on the display of the div element workaround. I had to test on the element’s form property to see if progress was supported. If you access the element, and it isn’t null, and the form property is defined, then the progress element is supported. You can’t test using nodeName, because all browsers return PROGRESS. Unfortunately, there is no elegant way to test for type of DOM object, such as HTMLProgressElement. There’s a hack I found at Sam Ruby’s weblog but that doesn’t work for IE, and again, Chrome and Webkit on the PC had problems with any programmatic access of the element.

You can’t provide a text description of the percentage by using the element’s innerHTML property. I didn’t try creating a new text node and attaching it to the progress element, but I don’t expect this approach to work, either.

You also can’t set a minimum value. The test case the WebKit developers attached for the new element uses the dir attribute to “reverse” the display.

update

I checked the HTML5 spec definition for progress again and found:

Content model:
    Phrasing content, but there must be no progress element descendants.

The HTML editing and WYSIWYG tools and validators are just going to love this. Anyway, supposedly this does mean that the element can take text. This must mean, then, that the Webkit implementation is incorrect.

second update

I created a variation of the application that embeds the fallback approach within the progress element itself. This seems to work fine. It cuts down a couple of lines of code, and at least looks a little more graceful (though it’s not valid). Note that I had to turn off the display of the elements by default, as Webkit nightly sets the background on the progress element to be transparent by default.

Last Update

The WebKit installation is most likely correct in its handling of the text for the progress element. According to the specification:

Authors are encouraged to also include the current value and the maximum value inline as text inside the element, so that the progress is made available to users of legacy user agents.

Though not a directive to the user agents, we have to assume from this statement that UAs are not supposed to display the text if the progress element is supported. However, the direction is unclear, one has to make an assumption that this is what’s happening in the browser.

This also means that if a person wants to include a text description of the progress, as I do in my original approach—something that happens frequently— you can’t. Instead, you’ll have to overlay the progress element with a div element and add the text to it.

You also have to use getAttribute and setAttribute to get and set the element’s value attribute. Accessing the attribute directly only works when the element is supported.

Frankly, I will never use the progress or meter elements. They are inferior, less accessible, more cumbersome options compared to what we have today. That the elements were poorly thought out is obvious when one tries to actually implement them.

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.

Categories
HTML5 Specs

HTML5: end of one chapter, start of another

I had planned on providing more edits to my change proposals, but doing so is only throwing good time away on a hopeless cause. I can’t even get the HTML5 co-chairs to realize that by allowing those who proposed a counter-proposal to group all of the items in only one response, they’ve made individual discussion on each change proposal, impossible.

I also can’t discuss most things on the list without being told to take it off-list. I feel as if the co-chairs are continuously taking me to the wood shed—it’s been, frankly, a humiliating experience.

I have no recourse but to quit the group. Evidently, the W3C does not find me a useful participant.

I’m not done with HTML5, but I am done with the HTML WG. I think HTML5 has significant problems, and I think the way the specification is currently written is going to cause a lot of confusion and problems in the future. But if I write on HTML5 going forward, it’s as a “citizen”, and not part of a group that says it wants to hear responses from the web community at large, but in actuality, just wants to rubber stamp what some of the browser companies want.

Categories
HTML5 Specs

Remove the Hidden attribute

My change proposal for Issue 95 is about removing the hidden attribute[1]:

The HTML5 specification states the following about this attribute[2]:

All HTML elements may have the hidden content attribute set. The hidden attribute is a boolean attribute. When specified on an element, it indicates that the element is not yet, or is no longer, relevant. User agents should not render elements that have the hidden attribute specified…

The hidden attribute must not be used to hide content that could legitimately be shown in another presentation. For example, it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar. It is similarly incorrect to use this attribute to hide content just from one presentation — if something is marked hidden, it is hidden from all presentations, including, for instance, screen readers.

The hidden attribute section provides one example: a game screen is hidden until a person has logged in.

Rationales for Keeping the Attribute

The HTML5 editor, Ian Hickson, wrote the following rationale as reason for rejecting this change in the associated bug[3]

Rationale: hidden=”” is a key part of HTML5’s accessibility story and represents one of the main accessibility improvements over HTML4 for dynamic applications.

A counter-proposal has been provided to keep the attribute. The rational given is[4]:

Authors of web documents and applications often need to temporarily hide certain content from readers and users.

Via a combination of script and CSS, such functionality is possible to build today, and there are hundreds of such implementations extant on the web. It’s clear that hidden=”” Solves Real Problems.

Attempting to implement such functionality with JavaScript and CSS is fundamentally more difficult and error-prone than hidden=””. hidden=”” is literally the simplest thing that could possibly work, and thus we Avoid Needless Complexity in its design.

By making it as easy as possible to author, and by defining uniform UA behavior (unlike bolt-on scripts which emulate this functionality), we preserve our Priority of Constituencies.

Bolt-on emulations of hidden=”” can fail to correctly hide content in a media-independent way, resulting in a degraded experience for users of aural browsers and other AT tools. hidden=”” thus promotes Accessibility more than bolt-on alternatives.

In addition, the Accessibility TF discussed the change proposal[5], and among the benefits discussed were the following:

  • Not so strong on keeping the hidden attribute.
  • Hidden does what the ARIA equivalent does, and seems useful.
  • Could live without it given we will get it in aria.
  • It’s like display:none but without the nasty side effects.
  • It is slightly different from aria-hidden…
  • HTML5 hidden applies to ALL elements
  • Not sure this has an accessibility impact…
  • There is some impact (but not a lot).

The Accessibility Task Force also provided a general statement regarding this element and others:

RATIONALE: The F2F believes these elements are actually useful for accessibility. We note that features similar to the elements in question are today created using elements with different semantics actuated by style and script, whereas we prefer native elements.

Response

I took a best guess effort at summarizing the rationales for keeping the hidden attribute.

  • It provides accessibility support where none existed in HTML4
  • Implementing the hidden functionality with JavaScript and CSS is difficult and error-prone
  • It’s the simplest thing that can work
  • It works with all media
  • It is semantically meaningful

I say “best guess” at summarizing, because the discussion points from the Accessibility TF seem to indicate that some members of the discussion don’t think the hidden attribute is particularly useful.

I do agree with the counter proposals that the hidden attribute is easy to use. From the example in the specification—set the value to true, to hide the element’ contents, false, to display the contents—you can’t get a simpler attribute. I also agree that HTML4 did not have an equivalent functionality built into the specification. However, I do not agree with the other statements given.

The Existing Behavior with JavaScript and CSS, Media, and Simplicity

The HTML5 specifications defines the rendering for the hidden attribute to be equivalent to setting the element’s display property to “none”[6]. You’d get the same effect with the following code:

document.getElementById("elem").style.display="none";

Or the following code:

document.getElementById("elem").setAttribute("style","display:none");

As you would setting the hidden attribute:

document.getElementById("elem").hidden=true;

You could even absolutely, positively, completely ensure the accessibility of the effect, using the following:

[aria-hidden="true"]
{
   display: none;
}
...
document.getElementById("elem").setAttribute("aria-hidden","true");

If any user agents do render content when the element’s display property is set to “none”, it’s the fault of the user agent, not the CSS or aria-hidden attribute. If user agents have problems with display being set to “none”, they will continue to have problems with the hidden attribute because the two are equivalent.

As for simplicity, both approaches are again, exactly equivalent.

The Semantics of Irrelevance

The hidden attribute was once named the irrelevant attribute, supposedly because the attribute is used to mark the contents of whatever element it is attached as “irrelevant”. The attribute was renamed because, a) the irrelevant term was confusing, and b) techs misspell words like “irrelevant”.

Is the content truly irrelevant, though? Consider the definition for the attribute:

Elements in a section hidden by the hidden attribute are still active, e.g. scripts and form controls in such sections still execute and submit respectively. Only their presentation to the user changes.

An irrelevant element is not one that is active, receiving events, participating in the web page, or form submission. The only truly irrelevant page component is one that doesn’t exist. If people want a truly irrelevant page section, they should use the DOM to create and remove the element, as needed. There is nothing about the behavior associated with removing an element from user agent rendering that is made more meaningful using a single-purposed HTML attribute, rather than using a simple combination of CSS property and ARIA attribute. Both have to do with the presentation of the element.

Presentation with the hidden attribute isn’t an incidental purpose, it is the primary purpose of the attribute. Rather than separate presentation and structure, it firmly welds the two.

Accessibility

The hidden attribute is no more accessible than setting the element’s CSS display property to “none”, because the two are equivalent.

However, the hidden attribute can be detrimental to accessibility because there’s nothing in the HTML5 specification that describes the precedence of settings. The ARIA documentation states that ARIA settings, such as aria-hidden, take precedence over settings such as display=”none”. Does the aria-hidden attribute have precedence, then, over the hidden attribute? How about when hidden is set to true, but a CSS stylesheet sets the display property of the element to “block”?

Introducing hidden introduces a redundancy, yet the documentation for hidden does not take such redundancy into account when defining the attribute.

Costs

The costs for an attribute such as hidden, are not as high as a more complex object, such as the details element. However, there are costs. Lint tools and validators now have to ensure conforming use of the attribute, HTML editing tools and WYSIWYG applications have to incorporate the new functionality, libraries have to be modified, books updated, design themes modified, and so on.

Web developers and designers have to spend time trying to figure out when to use CSS, and when to use the hidden attribute. I can imagine the many discussions about ‘irrelevant” content, and what does “irrelevant” mean in one context or another. It is an esoteric concept, and as such adds unnecessary complexity.

If the attribute provided something useful, it might be worth the costs. However, the hidden attribute provides absolutely nothing that we don’t already have.