Back in March 2004, David F. Miller demonstrated a little bit of DOM scripting magic in his A List Apart article Zebra Tables.
His script programmatically adds two alternating CSS background colours to table rows, making them more readable and visually pleasing, while saving the document author the tedious task of manually assigning the styling to large static data tables.
Although David’s original script performs its duty well, it is nonetheless very specific and limited in its application. It only:
- works on a single
table, identified by itsid, with at least a singletbodysection - assigns a background colour
- allows two colours for odd and even rows
- acts on data cells, rather than rows, and then only if they have no class or background colour already defined
Taking it further
In a recent project I found myself needing to apply a striped effect to a medium sized unordered list. Instead of simply modifying the Zebra Tables code for this particular case, I decided to completely recode the script to make it more generic.
Being more general purpose, the function in my splintered striper experiment is necessarily more complex. Where the original script only expected a single parameter (the id of the target table), the new function is called as follows:
striper('[parent element tag]','[parent element class or null]','[child element tag]','[comma separated list of classes]')
This new, fairly self-explanatory function:
- targets any type of parent element (and, if specified, only those with a certain class)
- assigns two or more classes (rather than just two background colours) to the child elements inside the parent
- preserves any existing classes already assigned to the child elements
See it in action
View the demonstration page for three usage examples. For simplicity’s sake, we’re making the calls to the striper function from the body’s onload attribute. In a real deployment situation, we would look at attaching a behaviour to the onload programmatically — just remember that, as we need to pass variables to the striper function, this would involve creating a wrapper function which would then be attached…something like:
function stripe() { striper('tbody','splintered','tr','odd,even'); }window.onload=stripe;
A final thought
Just because the function is called striper does not mean that it’s limited to purely applying a striped look; as it’s more of a general purpose “alternating class assignment” script, you can achieve a whole variety of effects with it.


Comments
Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.
Got something to add? You can leave a comment below.
15/12/2005
For brazilian people, this same article in Brazilian portuguese, with inclusion of “sort table”. http://ruf.rockgrafia.com/?art_id=52
Vote Helpful or Unhelpful
15/12/2005
bartts…not quite “this same article”, now is it? it’s a rough translation of the original “zebra tables” one.
Vote Helpful or Unhelpful
15/12/2005
This script could very easily have been modified to allow the input of an Object or Id as well as a tag name in the first parameter, just to make it possible to apply it on a single element instead of all lists, all tables etc.
otherwise, good article
Vote Helpful or Unhelpful
15/12/2005
Just wondering—might it be possible for someone to compile all of these articles into a zip file or pdf complete with the graphics, scripts, etc. for us to download and keep on hand for future reference? I have enjoyed them so far and would really like to have them for easy reference.
Vote Helpful or Unhelpful
15/12/2005
It will be nice when CSS3 gets supported widly enough to use
tr:nth-child(even) { background-color : #eee; }
instead of the javascript approach. Until that time though, this method is very useful.
Vote Helpful or Unhelpful
15/12/2005
I stripe my tables using Behaviour combined with cssQuery (for CSS3 selector support) to apply the className “even” to “tr:nth-child(even)”s, while changing the background colour in the css file (using the .even {...}).
Vote Helpful or Unhelpful
15/12/2005
Here comes my 2 cents…
I made an article based on Miller’s ZebraTables on my blog (portuguese).
And the final conclusion comes here
And if you wanna sort the values…
:)
Vote Helpful or Unhelpful
15/12/2005
You can avoid the extra function definition (which, besides looking clumsy, puts an unnecessary variable in your global namespace) to attach the call to striper() to the onload event, you can use an anonymous function like so:
window.onload = function() {striper('tbody','splintered','tr','odd,even');}Also, if you have existing onload events, you can check out Simon Willison’s tutorial on how to avoid overwriting them:
Vote Helpful or Unhelpful
15/12/2005
Out of curiosity how does this scale for a table of 100 rows? 1000 rows? Just curious – I’ve tinkered with the JS solution before and it didn’t scale well – resorted to server-side ASP/PHP…
Vote Helpful or Unhelpful
16/12/2005
This is awesome. I’ve been using the zebra code to stripe the tables on my tennis team’s site, and it’s always been a PITA to remember to set the ID and update the onload function with any new tables I add. Not only that, but the zebra forces you to put style information in the call to the function; here, it’s in the stylesheet where it belongs. Thanks for a great timesaver!
Vote Helpful or Unhelpful
16/12/2005
john, if you do have the means to do it server-side i’d always go for that.
what do you mean exactly with your query on scaling? are you wondering about how long it would take to execute and/or slow the browser down?
Vote Helpful or Unhelpful
19/12/2005
Thanks Patrick for finally getting this out the door. I guess you could say that I was a beta tester of this script ages ago. It’s great. It provides so much flexibility.
I’ve used it on a heavy traffic intranet with some pretty huge tables. So far, there has been absolutely no performance issues.
Enjoy the new candy cane striping joy!
Vote Helpful or Unhelpful
22/12/2005
candy cane! darn, and there i was trying desperately to come up with a christmassy angle for the demo…obvious in hindsight.
Vote Helpful or Unhelpful
31/12/2005
Strangely, it seems to work for tables but i didn’t manage to get it to work with ULs…
Vote Helpful or Unhelpful
03/01/2006
If you change line 29 to
if ((parentElementClass == null)||(currentParent.className.indexOf(parentElementClass))) {then you can do something like this
ul class="videos striped"and it will match. This lets you apply more than one class to your parent element.
Vote Helpful or Unhelpful
Impress us