CSS Vertical Bar Graphs

Here's a fairly typical vertical bar graph showing a hypothetical set of quarterly data for, say, invoice and collection totals. The difference here is that the whole thing is a simple set of nested lists and CSS. Really.

Q1

$18,450.00

$16,500.00

Q2

$34,340.72

$32,340.72

Q3

$43,145.52

$32,225.52

Q4

$18,415.96

$32,425.00

$50,000

$40,000

$30,000

$20,000

$10,000

It's pretty much all positioning. Actually, once you figure out how you want the graph to look, figuring out how to position things is fairly simple. The (comparatively) hard part is in figuring out how to calculate the heights of the various vertical bars and the horizontal "strata". This could be done in PHP, ASP, or some other server-side processing engine; via JavaScript on the client side; or manually by someone who really loves their calculator.

You can view source to see how simple it is, or here's the same list with the inline styles, classes, and IDs stripped away.

Q1

$18,450.00

$16,500.00

Q2

$34,340.72

$32,340.72

Q3

$43,145.52

$32,225.52

Q4

$18,415.96

$32,425.00

$50,000

$40,000

$30,000

$20,000

$10,000

Here's how it works: the data from each quarter is contained in a list item. This list item contains the label (e.g., "Q2") and a nested list that has one list item for the invoices, and one for the collections. The ul element is positioned with the desired height and width, which are here expressed in pixels.

The four quarters are absolutely positioned with respect to the ul element using position: absolute. They're all the same size, and only the value of left changes for each one. From there, it's a simple matter to absolutely position the sent and paid bars inside each quarter-box (which, being positioned, acts as the containing block for the bars). A little extra positioning to place the numbers, and we have our basic layout.

The "ticks" (the horizontal bars) are created with a few divs that all have the same height and stack one atop another. Since everything that comes before them in the list is already positioned, we don't have to absolutely position the divs. They just drop into place. The labels are placed just outside the tick-divs with some simple absolute positioning of their own.

The last bit is adding colors and gradient background images, which is straightforward enough.

The graph probably won't look as nice on IE/Windows as it does in Firefox, Safari, or Opera, since the graph uses PNGs with full alpha channels to create the fades on the graph background as well as the vertical bars. Try this visually flatter but more IE/Win-friendly version, should you be so inclined.