tonic tonic - 5 months ago 41
jQuery Question

CSS to set the background color for just a percentage of the width of a table row

I have a basic table with two columns: name and value. I'd like to shade each row in the table an appropriate percentage of the width based on the size of the value (to essentially create a sideways histogram!). I can write code to calculate the appropriate percentage to set, but I can't figure out the CSS to actually shade each row appropriately. It seems like the whole row can be shaded, but not a percentage. Is that true?

FWIW, I'm using Twitter Bootstrap and I can use jQuery too if need be. This is only running on Chrome so CSS3 & Webkit only is fine! Here's the HTML.

<table class="table">
<tbody class="lead">
<tr>
<td>
Joe
</td>
<td>
10
</td>
</tr>
<tr>
<td>
Jane
</td>
<td>
20
</td>
</tr>
<tr>
<td>
Jim
</td>
<td>
2
</td>
</tr>
</tbody>
</table>


Any tips on how to make this happen? Hope this question makes sense.

Answer

You could use linear-gradients.

If the percentage is 40%:

table{
    background: -webkit-gradient(linear, left top, right top, color-stop(40%,#F00), color-stop(40%,#00F));
    background: -moz-linear-gradient(left center, #F00 40%, #00F 40%);
    background: -o-linear-gradient(left, #F00 40%, #00F 40%);
    background: linear-gradient(to right, #F00 40%, #00F 40%);
}

Demo

So, in JavaScript,

var percentage=40,
    col1="#F00",
    col2="#00F";
var t=document.getElementById('table');
t.style.background = "-webkit-gradient(linear, left top,right top, color-stop("+percentage+"%,"+col1+"), color-stop("+percentage+"%,"+col2+"))";
t.style.background = "-moz-linear-gradient(left center,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)";
t.style.background = "-o-linear-gradient(left,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)";
t.style.background = "linear-gradient(to right,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)";

Demo


If you want to apply this to each row differently:

var col1="#F00",
    col2="#00F";
var els=document.getElementById('table').getElementsByTagName('tr');
for (var i=0; i<els.length; i++) {
    var percentage = Number(els[i].getElementsByTagName('td')[1].firstChild.nodeValue);
    els[i].style.background = "-webkit-gradient(linear, left top,right top, color-stop("+percentage+"%,"+col1+"), color-stop("+percentage+"%,"+col2+"))";
    els[i].style.background = "-moz-linear-gradient(left center,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)" ;
    els[i].style.background = "-o-linear-gradient(left,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)";
    els[i].style.background = "linear-gradient(to right,"+col1+" "+percentage+"%, "+col2+" "+percentage+"%)" ;
}

The problem is that setting the background to the tr works well on Firefox and Opera, but on Chrome the gradient is applied to each cell.

This problem can be fixed adding this code (see http://stackoverflow.com/a/10515894):

#table td {display: inline-block;}

Demo

Comments