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)
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)
Share edited Nov 7, 2014 at 3:46 Jollywatt asked Nov 7, 2014 at 0:18 JollywattJollywatt 1,3652 gold badges12 silver badges31 bronze badges 05 Answers
Reset to default 3There 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";
}
}
Turns out using jQuery is much simpler than any sort of CSS hack:
rows = $('table tbody tr');
rows.find('tr:visible:odd').css('background-color', '#f7f7f7');
And to specify styles for both even and odd:
rows.find('tr:visible').each(function(i) {
if (i%2) {
$(this).css('background', '#f7f7f7');
} else {
$(this).css('background', 'none');
};
});
I know, I've answered by own question—I should have made it clear that I can use jQuery!
I just wish :visible
and :even
would hurry up and make it into the CSS standard.
I've just managed to solve this by just adding an extra <tr>
element with display: none;
set (via CSS in my case but could use a style attribute) when a block of hidden rows has an odd number of elements. This won't meet every use case, but for cases where you're using multiple rows to create expanding tables it works quite well.
Not sure this is possible with pure CSS. Using display:none;
and visibility:hidden;
the items still exist in the DOM and so the table background color is displayed incorrectly. You can get this to work using JQuery remove()
You can see my simple example on js.fiddle here
Pure CSS (no JS) solution:
The trick is to hide a row with different tag, not class. "ul/li" tags must go. In my example I use "del" tag to hide.
.list div:nth-of-type(odd) { background: ghostwhite; }
.list del { display: none; }
<div class="list">
<div>1</div>
<div>2</div>
<div>3</div>
<del>4</del>
<div>5</div>
<del>6</del>
<div>7</div>
</div>