jQuery Table Striping Bug
Posted on June 17, 2008 in Tutorial | 4 Comments »
I have been using jQuery to do table striping, and up until today, I have not had any problems with it.
I had just been using the :even and :odd selectors to add classes to each table row.
Here is the code that I have been using:
$(document).ready(function(){
$("table.striped tbody tr:odd").addClass("odd");
$("table.striped tbody tr:even").addClass("even");
});
Seems easy enough. Then I just styled the odd table rows like so:
table.striped tr.odd td { background-color: #f0f0f4; }
One thing to note is that the :even and :odd selectors are zero-indexed, so the first table row will have a class of even, and not odd. Here is an example showing this simple striping.
Multiple Striped Instances
The situation that I had today had two different tables that were being striped. So based on the code, you would think that there wouldn’t be a problem. Here is the example with two striped tables on the same page.
Weird, so it looks like the first table row in the second striped table has a class of even instead of odd. I thought that the client may not like that because the two tables were not consistent, so I tried to think of another way to do the striping.
The nth Child
So based on the documentation, it looks like the nth child selector would be the solution. I just modified my JavaScript like so:
$(document).ready(function(){
$("table.striped tbody tr:nth-child(odd)").addClass("odd");
$("table.striped tbody tr:nth-child(even)").addClass("even");
});
As a note, the nth child selector is not zero indexed, so the first table row will have a class of odd instead of even. Here is the fixed example.
Conclusion
From what I can tell, this does not appear to be a browser problem, but a bug in jQuery. I have checked this in Firefox, Safari, IE6 and IE7.

























fwolfJune 18, 2008 at 7:36 am
so basically the counter is not being reset when performing yet another “table striping”-session, aint it?
I havent looked into the source yet, but normally you would create a oddeven-chooser-function like this, ie. using a row counter and then % 2 (true = odd, false = even).
cu, w0lf.
Andy CouchJune 18, 2008 at 10:55 am
I don’t think this is a jQuery bug. In fact, I would consider this a feature. In your selector, you are telling jQuery to collect all TRs that are inside TABLEs with the “striped” class that appear in the document and then differentiate between the even and odd ones. You aren’t telling jQuery to reset the counter when it encounters a new table. While this might seem like something that should happen automatically, there are many use cases where you wouldn’t want that to happen. I think this is all just part of the power of jQuery. So the easy fix is to just group each table into its own collection, which gives each on its own index. And you could do that with something like this…
$(document).ready(function(){
$(“table.striped”).each(function(){
$(this).find(“tbody tr:odd”).addClass(“odd”);
$(this).find(“tbody tr:even”).addClass(“even”);
});
});
I’m not saying your solution is wrong. This is just another solution that would work too. There are probably a 100 other ways to do it as well.
PeteJune 18, 2008 at 12:56 pm
Nice post, but Andy is right. I tried his changes on your tables, and they work like a charm. Sometimes the obvious isn’t so obvious, and I keep stumbling upon dozens of ways to do similar things in jQuery.
Keep up the good work!
TrevorJune 18, 2008 at 1:07 pm
@Andy and Pete-
I see what you are saying. But with that, wouldn’t the nth-child selector work the same way?