6

I have a table displaying a tree structure (Super- and Subcategories). When the user clicks on a supercategory, the display property of the childs is toggeled.

Now I want to add an alternating background color on every second table row - but of course taking only those into account which are currently visible. Below is a simplified example of the structure:

<table>
    <tr data-level="0"><td>Super 1</td></tr>
    <tr class="hide" data-level="1"><td>Sub 1</td></tr>
    <tr data-level="0"><td>Super 2</td></tr>
    <tr class="hide" data-level="1"><td>Sub 2</td></tr>
    <tr class="hide" data-level="1"><td>Sub 3</td></tr>
    <tr class="hide" data-level="1"><td>Sub 4</td></tr>
</table>

When the user clicks on the "Super 2" element, the "hide" classes are removed from the child elements.

I tried several selectors, e.g.:

/* Ugly result (dosn't recognize that elements are hidden) */
tr:nth-child(2n)
{
    background-color: grey;
}

/* Doesn't work at all */
tr:visible:nth-child(2n)
{
    background-color: grey;
}

/* Not what I inteded to do */
tr:not(.hide):nth-child(2n)
{
    background-color: grey;
}

I hope I got clear on what i want to do.

Is that possible with CSS or should I write a JS script that recalulates the even and odd rows whenever anything changes? Thanks in advance for any hints!

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Oromis
  • 347
  • 4
  • 13
  • 1
    This gets asked a lot - the typical answer is that it's not possible with pure CSS (until CSS4 maybe), so in the meantime you'll need to do all this in JS. In fact, the `:visible` selector is really a non-standard selector that appears in jQuery/Sizzle and maybe a couple of other libraries. – BoltClock Mar 11 '12 at 17:02
  • possible duplicate of [Style using nth-child to keep table's aspect (alternating row colors) updated](http://stackoverflow.com/questions/9216398/style-using-nth-child-to-keep-tables-aspect-alternating-row-colors-updated) – BoltClock Mar 11 '12 at 17:11

3 Answers3

2

You said the hide class is removed onclick.
Keep it simple, and add a class IE: "show".

.show tr:nth-child(odd)    { background-color:#eee; }
.show tr:nth-child(even)   { background-color:#fff; }

Edit:
I'll blame exaustion, but I think this might be the correct syntax.

tr.show:nth-child(odd)    { background-color:#eee; }
tr.show:nth-child(even)   { background-color:#fff; }
Bradmage
  • 1,233
  • 1
  • 15
  • 41
  • This fails in a similar fashion as the third rule in OP's code. See the possible duplicate link I just added. – BoltClock Mar 11 '12 at 17:09
  • I haven't had a chance to test the above yet. But the difference is my answer assumes the ability to add the class "show" to the appropriate TRs, based on "...the "hide" classes are removed..." Which I'm sure should get around the issue using "tr:not(.hide):nth-child". Definitely curious though, Gonna check it out more tonight. – Bradmage Mar 11 '12 at 18:54
1

The up-to-date and faster way to do the job is :

$('tr').removeClass();
$('tr:not(:hidden)').filter(':odd').addClass('odd');

Then you can style those odd lines in CSS with .odd {}

lapin
  • 2,098
  • 2
  • 21
  • 30
  • Where does class `odd` come from? – Bernhard Döbler Aug 16 '16 at 13:30
  • 1
    @BernhardDöbler I just updated the answer. The question is about "selecting" every second visible line, which is performed by : `$('tr:not(:hidden)').filter(':odd')`. I then just add an ".odd" class to those lines so I can easily style them in CSS. Chosen answer does the same, but is just less performant. – lapin Aug 18 '16 at 01:21
1

This jQuery snippet will do the job:

$('tr').removeClass('alternate')​
$('tr:not(.hide):odd').addClass('alternate')​

Play with it on the jsFiddle

Manuel Ebert
  • 8,429
  • 4
  • 40
  • 61