I've got a table with multiple <tbody>
elements. At a given time, only one <tbody>
is displayed, or all of them are displayed.
I currently use this CSS3 code to stripe the table:
table tr:nth-child(even) {
background: #efefef;
}
When a single <tbody>
element is shown, everything is (obviously) fine, but when multiple <tbody>
elements are shown the CSS rules apply to each one separately, and each <tbody>
has its own “stripes system”. Together the stripes may or may not look consistent, depending on the number of rows.
<tbody>
<tr> [ODD]
<tr> [EVEN]
<tr> [ODD]
</tbody>
<tbody>
<tr> [ODD]
<tr> [EVEN]
</tbody>
…
Would I absolutely have to use JavaScript (… jQuery) to fix this? Or is there a pure CSS solution?
You may use more than one <tbody> per table as long as they are all consecutive.
Tap into the tr (table row) element is CSS. Use the nth-child() selector and add background-color of your choice to all odd (or even) table rows.
If you're using jQuery then use the :even
selector, (edited: to handle visibility) like this:
$("table tr:visible:even").addClass("even");
And a class like this:
.even { background: #efefef; }
Again, that's if you're using jQuery already, if you're not go with a pure javascript solution (including any library for just this is overkill) like bobince posted. Either way I don't see a pure CSS solution here...it's definitely a valid case, but not something that comes up often enough to make it spec-worthy.
If you have rows that are all the same height, you can cheat with a gradient, e.g.:
#table {
background-image: repeating-linear-gradient(pink 0, pink 1.6em, yellow 1.6em, yellow 3.2em);
background-repeat: no-repeat;
/* To account for headers; adjust size to account for footers.
* You can also use a second (or third) gradient for both.
*/
background-position: 0 1.4em;
}
If you can guarantee that all <tbody>
elements have an even number of rows, you can also make use of that (even if the last one is hidden), but otherwise, you’re out of luck. Selectors Level 4 might have something to say about it, though, with something along the lines of
#table > !tbody > tr:last-child:nth-child(even)
making up for the class.
Demo!
After intensive research, I can state that
All solutions you would think of are impossible:
Use the :nth-child
pseudo-class.
Verdict: This will only work within a single parent.
Somehow involve the tbody
tags with odd number of rows (color switchers) by counting their children and distinguishing those with odd rows in a similar way nth-child(odd)
works.
Verdict: In CSS it is not possible to count children, see this question. Beware of the confusing accepted answer - this is in fact counting siblings, not children
Try to match only some tbody
s based on some children CSS rule, and thus being able to identify tbody
s with odd number of children.
Verdict: In CSS it is not possible to match elements according to their children:
CSS4 introduces a new selector :nth-match
, which sounds promising as it doesn't contain the word "child" in it. So you would wonder if this would work:
:nth-match(even of tr) { background-color: #ccc; }
:nth-match(odd of tr) { background-color: #fff; }
Verdict: It doesn't work. If you look at the description, you see it will do exactly the same thing you observe:
The
:nth-match(An+B of <selector>)
pseudo-class notation represents an element that hasAn+B-1
siblings that match the given selector list before it in the document tree.
The problematic is the word siblings which mean it will only count within each tbody tag, as the :nth-child
selectors do.
There is no pure CSS (neither CSS3 nor CSS4) solution. You will have to refrain to either:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With