Joseph Joseph - 2 months ago 10
Javascript Question

Zebra stripes ignoring hidden elements

Say I have a table whose rows can be dynamically assigned

.hidden
classes. Rows with that class are hidden via CSS. The rows are also styled with alternating colours, like so:

tr:nth-child(even) {
background-color: $light-grey;
}


However, I want every even, unhidden row to be shaded. So hidden rows are not counted when
:nth-child(even)
is applied, and the pattern appears consistent. The following is my immediate attempt, but it doesn't do what I'm hoping for.

tr:not(.hidden):nth-child(even) {
background-color: $light-grey;
}


:nth-child()
is simply referring to the rows' original indices, not the current selection scope from
tr:not(.hidden)
. The two are simply 'filtered through' on top of one another.

Is there a
:nth-of-scope/selection()
(or simply
:nth()
) meta class in CSS? Are there any equivalents or alternate methods?

Or must I resort to Javascript?

(I should say that I can also use jQuery)

Answer

There is no way to do this in pure CSS as adding display:none or visibility:none doesn't remove the elements from the DOM, which is what CSS uses.

As a result, you will need to add a little JavaScript (which runs once the page has loaded) to do this, like so

var trs = document.getElementsByTagName("tr"), // Select whichever ones you need
    count = 0; // Counter for the non-hidden ones

for(var i = 0; i < trs.length; i++) {    
    if(!trs[i].classList.contains("hidden") && (count++)%2 == 0) { // Odd ones
        trs[i].style.background = "black";
    } else if(!trs[i].classList.contains("hidden")) { // Even ones
        trs[i].style.background = "lightgrey";
    }
}