Yahoo! UI Library: ProgressBar

The YUI ProgressBar Control provides a visual means of showing progress of an on going operation. The ProgressBar can be enhanced via CSS styles to provide different colors, shapes and textures. The bar can move horizontaly or vertically, back and forth. The movement can be softened by using the Animation utility. A textual representation of the bar can be displayed, which is also available for WAI-ARIA screen readers.

Getting Started

To use the ProgressBar control include the following source files in your web page:

The ProgressBar control is defined by YAHOO.widget.ProgressBar, which extends YAHOO.util.Element.

Creating the Tree

Create a progress bar by instantiating ProgressBar with optional configuration attributes and then rendering into the element that will contain it:

You can supply initial configuration attributes. The render method is chainable so you can do all in one step:

The ProgressBar defaults to a simple blue bar moving from left to right. If the SAM skin is used it will show a color scheme compatible with other YUI components. The direction of movement can be changed up to the moment it is rendered. It can go from right to left or vertically from top to bottom or bottom to top. To create a ProgressBar moving from bottom to top, any of the following two segments can be used:

See the examples below in Using ProgressBar or the API Documentation for more details.

Using ProgressBar

This section describes several common uses and customizations of ProgressBar and contains these sections:

Moving the Bar

The length of the bar represents the value of the value configuration attribute. It is scaled so that the initial edge of the bar (on a bar with direction set to 'ltr' it would be the left edge) represents the minimum value set via the minValue configuration attribute and the end edge is set to maxValue. The value and range attributes are plain numbers in arbitrary units, the ProgressBar scales them to and from actual pixel values.

Animating the Bar

If the Animation utility is loaded, the ProgressBar can use it to move the bar. To enable it the anim configuration attribute has to be set to true. This attribute accepts either a boolean to enable/disable animation or an instance of YAHOO.util.Anim. When read, anim will return the instance of the Animation object created or null if there is none. The properties of the Animation object can then be changed to set the behavior of the bar, most often duration and the easing method. The following code makes the movement last for 3 seconds and bounce both at the start and end of the movement.

Setting Up your Style Definitions

The ProgressBar component makes use of several CSS classes to style the bar. You can either use the CSS provided in the download source, or you can create your own. If you create your own, you'll need to use the classNames the ProgressBar assigns to its elements.

SelectorAttributeDescription
.yui-pbwidth
height
overall size of the ProgressBar. It can also be set via the width and height configuration settings
.yui-pbbackground-image
background-color
background to be used on the area the bar is not covering
.yui-pbborderborder around the component
.yui-pb-barbackground-image
background-color
Image or color to use for the bar itself
.yui-pb-barmarginoffset from the edge of the ProgressBar to where the transparency of the mask starts.
.yui-pb .yui-pb-animbackground-image
background-color
Image or color to use for the bar while it is moving.
.yui-pb-mask divbackground-imagemask with transparencies to allow the bar to show through
.yui-pb-captionfont and othersthis style is not actually used by the ProgressBar, but is is defined in the SAM skin to be used to display the value of the bar
.yui-pb-rangefont and othersthis style is not actually used by the ProgressBar, but is is defined in the SAM skin to be used to display the end values of the bar

The elements that constitute the ProgressBar are stacked one on top of the other. They are accesible through configuration attributes which allows further styling, possibly dynamic. The attributes allowing access to the DOM elements are read-only. The following table enumerates the three layers, their classNames and attribute names:

classNameAttribute NameDescriptionz-index
yui-pbelementthe container of the ProgressBar itself0 (bottom)
yui-pb-barbarElthe moveable bar1
yui-pb-maskmaskElthe mask that may partially cover the bar2

To let the bar be seen through the mask that covers it, the mask has to have transparencies, a PNG or GIF file with transparency works. Since the opaque areas of the mask will hide some areas of the ProgressBar, you don't want the bar to move under those opaque areas, you want the zero (actually, the minValue) to start right at the transparent section and likewise you don't want it to reach beyond the transparency on the end edge. Thus, when using masks that take some space at either end, it is necessary to set the margins on the bar itself (.yui-pb-bar).

Since the ProgressBar derives from Element, all the methods inherited from Element apply to the main container for the widget. If we were to set the color of the background and the bar via code, we can do it like this:

The ProgressBar has a predefined style for the SAM skin (yui-skin-sam). Since this style is often set at the document body, if you want to customize a particular ProgressBar while retaining the skin for other elements in the page, these are the style definitions that will cancel those preset styles where #myProgressBar1 represents the id of the ProgressBar that is to be styled differently.

Responding to Events

The ProgressBar inherits from the Element utility the before and after change events for any of its configuration attributes thus, there is, for example, a beforeMinValueChange and a minValueChange. The before event listeners can return false to reject the change. They both receive the old and new values for the corresponding attribute.

The ProgressBar adds three events that signal the movement of the bar. The start event will be fired right before the bar is about to move. The progress event fires at least once in between. If animation is enabled, it will fire as many times as the Animation fires its own onTween event but it will scale the pixel value of the bar to a value in whichever units the implementer has set. Finally, the complete event fires when the bar reaches its set value. All three receive as its single argument the actual value that the bar represents at the instant they fire. For consistency, the progress event will fire only once when animation is not enabled.

Captioning

The ProgressBar does not directly handle captioning, however using the motion or attribute change events, any of its settings can be shown in any container. For a consistent look when using the SAM skin, the classNames yui-pb-caption and yui-pb-range have been defined to be used in the containers for the current value and the end values respectively. The following code shows how the current, possibly changing value and the minValue can be shown in their respective containers:

WAI-ARIA support

The ProgressBar supports WAI-ARIA as specified for the "progressbar" role, see: W3C spec. The ProgressBar container has tabIndex="0" and has role and role-specific settings as described in the document.

Since the ProgressBar cannot know what concept the value corresponds to, it cannot, on its own, provide a meaningful aria-valuetext text. The ariaTextTemplate configuration attribute allows the implementer to set the template to be used for that attribute.

The ProgressBar will produce a text assembled via YAHOO.lang.substitute from the template in the ariaTextTemplate configuration attribute. The ProgressBar makes the values of the value, minValue and maxValue available for substitute to use in the placeholders in the template.

Scaling of the mask

The normal mechanism for scaling images in a browser is not acceptable for scaling the mask. Masks are usually thin frames around the bar, often with small single pixel-wide features. With normal scaling, these features might be lost. Instead, the ProgressBar cuts the mask into four quadrants.

This set of diagrams show how the mask image is used. The blue sections enclosed in red at the top two images show a couple of masks of very different sizes, both made of the very same base image, which is shown below.

The red line outlines the container used to hold the mask which is of the same size as the overall ProgressBar. The container holds four quadrants of 50% width and height, marked by the yellow lines.

The same mask image is set as the background for each of the four individual quadrants but instead of letting it tile normally, we use the background-position CSS attribute so each is aligned to its own external corner. The blue area shows the corner section of the mask image that is visible in each quadrant, enclosed in between the ProgressBar edge in red and the edges of the quadrants in yellow, the light blue areas are the parts of the same image that fall outside of the quadrants and are invisible.

If the top ProgressBar were to be stretched a little more, the now invisible edges opposite each visible corner would start to show. On the other hand, if the lower ProgressBar were to be reduced, the yellow lines would start eating into the rounded inner corners and the inner contour would not blend but meet at an angle.

If we call A the length of the straight section of each edge and B the length of the section from the edge until the rounded inner corner meets the straight section so that the width of the original mask is A + 2 * B, we can use that image as a mask for any ProgressBar that is at least 2 * B on the side (no straight section visible) to 2 * A + 2 * B (the straight sections are seen twice, once in each contiguous cell).

Known Issues

The ProgressBar is affected by the bug: "JS positioned elements get misplaced on zooming" on Safari 4 and other recent WebKit derivatives.

ProgressBar is functional in the target mobile browsers.

ProgressBar Control Cheat Sheet:

Cheat Sheet for the ProgressBar Control.

Download full set of cheat sheets.

More Reading about the YUI ProgressBar Control:

YUI ProgressBar on del.icio.us: