Friday, August 21, 2009

Data Visualization: More CSS Positioning Examples

After our beginner's website design example, I want to change gears and do a more advanced tutorial. I had covered column graphs in a lot of detail recently, there are also horizontal bar graphs where the bars instead of going up go sideways to the right. This type of graph can also be programmed using pure CSS.

In cases where we want the horizontal label to show up to the right of the bar (such as when the
bar itself is very small), I was putting the label inside of a <span> and using relative positioning to move it to the right of the bar, like this:

.horizontalgraph ul.bars li span.outside {
position: relative;
color: black;
letter-spacing: normal;
right: -30px;
}

<div class="horizontalgraph" style= "height: 308px;">
<ul class="bars">
<li class="bar1 blue" style="width: 211px;"><span class="outside">100</span></li>
<li class="bar2 blue" style="width: 100px;"><span class="outside">46</span></li>
<li class="bar3 blue" style="width: 36px;"><span class="outside">9</span></li>
</ul>
</div>

CSS Positioning

The problem with that approach is that to accommodate numbers with greater number of digits we have to move it out far enough so that all the digits in the number appear to the right of the bar. Then for single digit numbers they end up hanging out in space, too far from the bar. See how 9 and 46 are positioned too far away from their respective blue bars while the 3-digit 100 looks fine.

So we need to take a different approach that causes the digits to be left justified and start
with the first digit just to the right of the bar.

To get the digits to align to the left we turn the span into a block element, give it a width, and set text-align to left. But as soon as we turn it into a block element, it will no longer be automatically positioned at the right side of the li. The li has text-align set to right to cause the labels to show up on the right end of each bar, but once we made the span into a block element, it's position is no longer affected by the li's text-align right.

The relative positioning of the span was in fact utilizing the li/text-align's layout data and setting off from where it would have been and moving 30 pixels to the right from there. But that was a "regular" span element. A block span element is a different animal.

But fortunately, there is another way to get the span positioned where we want it using absolute positioning. Since the li is the containing block, any absolute positioning will be done with respect to the li's box. The following CSS does just that:

 .horizontalgraph ul.bars li span.outside {
position: absolute;
display: block;
color: black;
letter-spacing: normal;
text-align: left;
width: 3em;
right: -42px;
}


CSS Positioning

All numbers come out looking good with the new CSS regardless of the number of digits that they have.

As an extra note, for example, if we were to say position: absolute; right: 0; the span's right edge would be positioned at the right edge of the li, no matter how wide the li is. Pay attention to the purple blocks which are as wide as 3em. They are positioned zero pixels from the right edge of the containing block which means their right edge sits on top of the right edge of the li element.

CSS Positioning

To push the span further to the right, we can specify a negative value for right. By specifying right: -42px we cause the right side of the span to be positioned 42px to the right of the li's right border, which turns out to be just about right.



Post a Comment