Validweb

Better Zebra Tables

Friday 11 February 2005

Note: this article was published over 4 years ago. Techniques, tools or technologies described in this article could be outdated. Please help me by notifying me of any broken links you might encounter.

In large tables it’s often hard to focus on one row, making it hard to extract data from the table. There are various scripts (client–side as well as server–side) floating around the net that provide the ability to style odd/even table–rows to aid readability of tabular data.

Almost a year after my comment at A List Apart, I still get quite a few hits for zebra.txt; my enchaned, more generic version of David F. Miller’s Zebra Tables script. My script wasn’t perfect either so I improved it and decided to elaborate on my changes.

If you’re not interested in how this works or what’s improved go and see the script in action or download it.

The original script

Zebra Tables is a script that applies different background colors to odd or even table–rows. More information is available at the original article Zebra Tables at A List Apart

While David F. Miller’s original script works as intended, there are a few things that I don’t like about it. I think the most important flaw is the lack of using CSS to apply styles to the table–rows.

My Zebra Tables

After looking at the script and various comments I decided to rewrite the script to make it more flexible. While the original script applies background–colors to the individual table–cells I think it’s better to apply a class to the table–row itself, then use CSS to style the table–cells.

I also made the script more generic by looping through all the tables in the document, if you just need certain tables to be striped you should use David Miller’s method using id’s or better yet; classes.

You can have a look at my previous zebra.txt, but since there’s a new and improved version I suggest you continue reading.

Better Zebra Tables

The script allows you to style rows using CSS, it uses two classes; The class ‘even’ is used for, well you guessed it, even rows. The class ‘ruled’ is used for the hover state of a table–row.

You might want to have a look at the example to see what I am talking about.

see example 1
figure 1: Striped tables in action

Multiple classes

The stripe function now adds the ‘even’ class in a way that existing classes won’t be overwritten, allowing for more complex table–row styles.

Hovers

I wanted to apply a hover-state for rows to make it even easier to distinguish tabular data. This could’ve been done from CSS alone, but unfortunately IE doesn’t support the :hover pseudo–class on anything other than links. I implemented Christian Heilmann’s method from The Table Ruler to add hover support to our zebra stiped tables.

In your CSS you might also want to apply Mark’s fix for Opera.

The new script


var stripe = function() {
  var tables = document.getElementsByTagName("table");  

  for(var x=0;x!=tables.length;x++){
    var table = tables[x];
    if (! table) { return; }
    var tbodies = table.getElementsByTagName("tbody");
    
    for (var h = 0; h < tbodies.length; h++) {
      var even = true;
      var trs = tbodies[h].getElementsByTagName("tr");
      
      for (var i = 0; i < trs.length; i++) {
        trs[i].onmouseover=function(){
          this.className += " ruled"; return false
        }
        trs[i].onmouseout=function(){
          this.className = this.className.replace("ruled", ""); return false
        }
        
        if(even)
          trs[i].className += " even";
        
        even = !even;
      }
    }
  }
}

window.onload = stripe;

Improvements

So there’s still room for improvement here, like adding support for table sorting, I might implement that later if I have time.

Note: I have tested this script, and it works well in IE5+, Firefox 1.0 and Opera 7 — all on windows. Despite Mark’s fix Opera 7 still messes things up slightly with the hover part on the last table–row. If you don’t need table–row hovers you can safely remove these lines:


trs[i].onmouseover=function(){
  this.className += " ruled"; return false
}
trs[i].onmouseout=function(){
  this.className = this.className.replace("ruled", ""); return false
}
« CSS Hacks Websites Nieuwe Stijl »