5

How can I add a background-color to every second table row even some table rows are not displayed?

In my HTML is a simple table with some table rows. Just like that:

<label for="cb">hide blue</label>
<input id="cb" type="checkbox" onchange="hideBlue(this.checked)" />

<table>
    <tr data-cat="red">
        <td>red car</td>
    </tr>
    <tr data-cat="blue">
        <td>blue jacket</td>
    </tr>
    <tr data-cat="red">
        <td>red bull</td>
    </tr>
    <tr data-cat="red">
        <td>red pen</td>
    </tr>
</table>

As you can see there is also a checkbox which can toggle the "blue" category-rows. My CSS is looking like that:

tr:nth-child(odd) {
    background-color:#aaa;
}

But now if someone hides the "blue" category (by adding a display:none-class), the background colors are not alternate right anymore. How can I prevent this failure?

I already tried to add :not(.displaynone) to the css rule but this didn't work.

Here is a jsFiddle

Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164
Werner
  • 2,126
  • 2
  • 22
  • 34
  • @MiheyEgoroff, try it... doesn't work. – GreyRoofPigeon Aug 25 '14 at 13:41
  • I'm afraid that it's not possible by CSS Selectors. Pseudo-classes such as `:nth-child` or `:nth-of-type` look through the children tree of the parent - not to a list of classes - to match the valid child element. Since the element remains in DOM, `tr.displaynone:nth-child(odd)` may or may not work. – Hashem Qolami Aug 25 '14 at 13:42
  • http://stackoverflow.com/a/9548096/2506493 might work for you, although it places some limiations on table layout/content. – quw Aug 25 '14 at 14:22

3 Answers3

3

There is a way to get the updating alternating row colors using only CSS selectors.

tr:nth-child(odd) {
    background-color:#aaa;
}

tr.displaynone ~ tr {
    background-color: transparent;
}

tr.displaynone ~ tr:nth-child(even) {
    background-color:#aaa;
}

What this does is it sets all siblings after the displaynone row background-color to transparent, and then sets the even rows after that background-color to #aaa.

This works for your example fiddle (forked here), but it will not work if you have to hide more than one element at once. (example, comment out the marked line and click on rows).

If you need to hide multiple rows at once, this solution will not work for you, and you'd have to use javascript to compute the row color whenever you hide/show rows.

quw
  • 2,844
  • 1
  • 26
  • 35
0

You haven't tagged jQuery, but I'm giving you it as an alternative anyways (also for other users who might stumble upon the same problem).

function loopTable() {
    var x=0;
    $("table>tbody>tr").each(function() {
        if( $(this).is(":visible")  ) {
            if( x%2==0 )
                $(this).addClass('red');
            else
                $(this).removeClass('red');
            x++;     
        }
    });
}

This function should be called on body load, and everytime the table is altered. Or on interval.

DEMO.

GreyRoofPigeon
  • 17,833
  • 4
  • 36
  • 59
  • 1
    It looks like you forgot to remove the `red` class on odd rows. [Fixed Demo](http://jsfiddle.net/oxz25x53/) – quw Aug 25 '14 at 14:42
0

As per your requirement only jquery can solve your problem. Even one <tr> is hidden the background color will be in sequence. Check DEMO.

Here is the jQuery Code.

$(document).ready(function(){

$("tr[data-cat='red']:even").css({'background':'red'});
$("tr[data-cat='red']:odd").css({'background':'orange'});
$("tr:not([data-cat='red'])").css({'background':'blue'});
});
Kheema Pandey
  • 9,977
  • 4
  • 25
  • 26