You can use this box
to change the value
of the bar.
Range: 0 - 100

Back to the index of articles and examples

Progress Bar

The following examples of the ProgressBar show several of its features. The Animation utility has been loaded so all bars move smoothly, otherwise they would respond immediately to changes in value. The values set in the floating box to the left will affect all of the bars below. All bars have the properties minValue and maxValue left at their default of 0 and 100. Values outside of this range will be ignored.

This is the most plain ProgressBar, it has been created by the following code:

pb = new Y.ProgressBar({contentBox:'#pb',height:'30px', width: 300, barColor:'green',
    backColor:'orange',border:'thin solid black'});
pb.render();

The contentBox property tells where to render it. Size attributes can be given as strings with units specified or numbers which will be interpreted as pixel sizes. Color attributes can be anything that a CSS color definition would take.


This is a more elaborate version. It was created by the following statements:

pbplain = new Y.ProgressBar({contentBox:'#pbplain'});
pbplain.render();

The shape and colors are the result of style definitions which use the #pbplain as part of their selector.

#pbplain.yui-progressbar-content {
	height:25px;
}
#pbplain .yui-progressbar-mask td {
	/* if you don't provide a mask, the bar will be a completely rectangular thing  with no borders */
	background-image: url(mask.gif);
}

#pbplain .yui-progressbar-bar {
	/* if you omit the image of the bar, it will be shown as a flat thing of the color given in attribute 'barColor' */
	background-image:url(bar.gif);
}
#pbplain.yui-progressbar-content .yui-progressbar-anim {
	/* if you omit the image of the bar, it will be shown as a flat thing of the color given in attribute 'barColor' */
	background-image:url(animbar.gif);
}

In the first one I'm changing the default height, leaving the width to the internal default (200px). The second definition sets the image that provides the rounded corners to contain the bar. This image can be stretched and shrunk as needed. The actual mask.gif image is 400*32px but here it is shown in 200*25px. The third definition provides the image to be used for the bar. It will be tiled to fit the space needed so it needs to be designed with a repeating tileable pattern. Finally, the last definition provides an image that will be displayed alternatively when the bar is moving.

The Progress Bar also fires some events when it changes values and also while it changes. Below, you can see the value of the bar above, updated while it is being changed.

This is done with the following code:

var settingEl = Y.get('#setting');
// This one shows it while moving
pb.on('changingEvent',function (value) {
	settingEl.set('innerHTML',value + ' ... moving ...');
});
// This will show at the end (even if there is no animation at all)
pb.on('completeEvent',function (value) {
	settingEl.set('innerHTML', value);
});

The bar itself is always a rectangle. To give it different shapes and borders, a mask is used. The mask should be a GIF or PNG file with transparency where you want the bar to show through. The mask can be opaque in the corners and transparent in the center, as in the previous example or you can also play with transparency and opaqueness anywhere in the graphics like the bar above.

The ProgressBar cuts the given mask vertically and horizontally right through the center of it and uses each corner separately. These four sectors slide to and from the center lines. If the mask has a repeating pattern, as this one has, you have to make sure that the width and height given are integer multiples of the basic pattern, otherwise it will not tile correctly. In this example, I have made the width and height one pixel wider and higher than it should have been. If you look at the center, you will see that the holes in the grid on the vertical and horizontal lines coming out from it are different in size from the others


This bar uses a mask that is not symmetrical in any way. It cannot be scaled. If you try to make it any different width, the ruler at the bottom will either have no 5 or have two of them if you shrink it further the 4 and 6 will disappear and so on. The bar, which looks like a wedge, is actually rectangular as it always is. The mask has a wedge-shaped opaque area in the upper-left corner, which is the same color as the page background. The bar is not tiling. The bar is a single image, the bar shows whatever needs of it. Here you have them both over a light gray background with blue borders around the two images:




The mask for this bar has some fancy caps at both top and bottom ends, those blue rounded things at each side. The bar cannot go from edge to edge of the ProgressBar container because it would hide behind the areas taken by those caps at the ends. To reserve space for them, we use the margin CSS attribute given along the image to be used for the bar, in this case, we are leaving 10 pixels at the left and right ends of the bar:

#pbthin .yui-progressbar-bar {
	background-image: url(thinbar.gif);
	margin: 0 10px;
}

The bottom of the empty area of the bar is the same silver background as the rest of the area around it, it simply looks deeper than the rest because of the inset shading of the mask.


ProgressBars can grow in any direction, as set by the direction attribute (case insensitive), which can take values 'lr' (left to right, the default), 'rl', 'tb' (top to bottom) or 'bt', as in this sample.

If the Animation utility is available, ProgressBar will use it. The instance of Animation in use is available in the anim attribute. You can set the attributes of the animation like duration or easing.

This is the code for this bar:

pbcopper = new Y.ProgressBar({contentBox:'#pbcopper',direction:'bt'});
pbcopper.set('anim',{
	duration:3,
	easing:Y.Easing.bounceBoth
});
pbcopper.render();

These setting make the bar grow from bottom to top, to last 3 seconds to make any changes and use the bounceBoth easing method

The space left blank by the bar is not transparent as in the previous examples. I have set a further background which shows in the 'empty' area. This was set through the following style:

#pbcopper.yui-progressbar-content {
	background-image:url(copperbackV.gif);
}

So, in the end, we have three layered levels in the ProgressBar, assuming we have a ProgressBar with an id of pbcopper as in these case, the CSS selectors for each of the layers, from bottom up, are:

  1. #pbcopper.yui-progressbar-content /* The area within the transparent section of the mask not covered by the bar */
  2. #pbcopper .yui-progressbar-bar /* The bar itself */
  3. #pbcopper .yui-progressbar-mask td /* The mask that will let the bar be seen through its transparencies */
There is a further selector to set the image of the bar while it is moving (provided the Animation utility is loaded) which is selected via the selector:
  • #pbcopper.yui-progressbar-content .yui-progressbar-anim

The selectors to be used for each of the characteristics of the ProgressBar seem quite random but, actually, have been forced by the way the widget is drawn. Many alternatives to make them as easy as possible have been explored, these are the best choices found.

WAI-ARIA support

The ProgressBar supports WAI-ARIA as specified for the "progressbar" role, see: W3C spec. The ProgressBar container has tabIndex="1" 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 ariaText setting allows the implementer to set a text to be used for that setting. The value set should contain a vertical bar character (|) which will be replaced by the actual value

API

The ProgressBar has no public properties, all settings are handled through methods get and set

Configuration Attributes

contentBox
Valid DOM element identifier or reference where the ProgressBar will be drawn. It can be set only once.
value
Numeric, default: 50, the value that will be represented by the bar
minValue
Numeric, default: 0, the minimum value for the bar. Settings of value below this will be ignored
maxValue
Numeric, default: 100, the maximum value for the bar. Settings of value above this will be ignored
barColor
Any valid CSS color specification, default 'blue' it will apply to the body of the bar. It will override settings done via StyleSheets
backColor
Any valid CSS color specification, default 'white' it will apply to the area left uncovered by the bar. It will override settings done via StyleSheets
border
Any valid CSS border specification, default 'none' it will apply to the whole of the widget. It will override settings done via StyleSheets
width and height
Any valid CSS width specification, defaults 200 wide, 20 high, a string including standard CSS units or any numeric value (which will be interpreted as pixel sizes)
direction
Either 'lr' (default), 'rl', 'tb', 'bt', sets in which direction the bar will grow from (left, right, top or bottom) in which direction. Once set it cannot be changed. Case insensitive.
anim
Read only. If the YUI Animation utility has been loaded, it will contain the instance of the Animation utility that this ProgressBar uses. The duration and easing setting are the most important to use.
barEl and maskEl
Read only. They contain references to the actual elements making up the ProgressBar. It's use is discouraged
ariaText
A formatting string to provide a meaningful text for WAI-ARIA aria-valuetext attribute. It should contain a vertical bar to be replaced by the current value of the control

Methods

Constructor
Takes an optional object literal with settings for the attributes listed above. Returns an instance of ProgressBar
render()
Draws the ProgressBar
redraw()
Redraws the ProgressBar with the current settings. It takes no arguments, it doesn't return anything
destroy()
Deletes the HTML code created and removes any event listeners attached to them

CSS styles

To make it easy to draw the most basic ProgressBar a few settings relating to presentation are provided. However, the code and presentation of the widget have been kept separate as much as possible. The programmer can write the code independently of the graphics designer. Once a ProgressBar instance is created, the programmer just needs to set the value, all other aspects of the presentation (except direction) can be handled through CSS styles

SelectorAttributeDescription
.yui-progressbar-contentwidth
height
overall size of the ProgressBar. Can be set via the width and height configuration settings
.yui-progressbar-contentbackgroundbackground to be used on the area the bar is not covering
.yui-progressbar-barbackground-image
background-color
Image or color to use for the bar
.yui-progressbar-barmarginoffset from the edge of the ProgressBar to where the mask transparency starts. If the bar goes into this area, it would be hidden behind the mask.
.yui-progressbar-content .yui-progressbar-animbackground-image
background-color
Image or color to use for the bar while it is changing
.yui-progressbar-mask tdbackground-imagemask with transparencies to allow the bar to show through

How it works

The diagram to the left shows the layers of the ProgressBar.

The green rectangle is the container which is the base for the whole control. It has the className .yui-progressbar-content.

The red rectangle is the bar itself, which occupies just part of the container and has className yui-progressbar-bar.

The blue area is the mask which has a transparent hole that allows the lower layers to be seen and has className yui-progressbar-mask.

The red bar does not start at the very edge of the container, because it would otherwise be hidden under the borders of the mask. The black vertical lines in between the top and bottom layers show these two do match while the red bar is offset by as much as set in its margin.

The blue mask is not a continuous image but it is made of four sections shown cut by the yellow lines.

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 table used to hold the mask which is of the same size as the overall ProgressBar. The table is divided in four cells 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 cells but instead of letting it tile normally, we use the background-position CSS attribute so each is aligned to its own corner. The blue area shows the corner section of the mask image that is visible in each cell, enclosed in between the table edge in red and the cell dividers in yellow, the light blue areas are the parts of the same image that fall outside of the cells 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).

Placing the mask in a regular <img> tag would allow for unbound stretching and shrinking by using the width and height attributes. The problem with this approach is that the definition and general appearance of the base image might be altered drastically. Lines 1px wide might become too wide or completely disappear, rounded corners will turn elliptical if stretched unevenly and generally, the image will loose resolution and become distorted.