4

Contrary to the duplicate notice, this question is not a duplicate. The purported duplicate does not address the case of nesting, something I've clearly explained in my question.

I have a table where rows can have one of two classes: parent or child. Some parents have many children, while others have no children. The HTML structure of the table, being flat, can not represent the hierarchical relationship between the rows; both parents and children are trs. Example:

Parent A
Child  1
Child  2
Parent B
Parent C
Child  1

I would like to stripe the rows so that odd and even parent rows have a color, and their respective children will have a lighter shade of the parent color.

Please see the included snippet for an example of what I'm trying to achieve.

table {
  border-collapse: collapse;
  width: 100%;
}

td {
  border: 1px solid #eee;
  padding: 10px;
}

.parentOdd {
  background-color: #eb94fa;
}

.parentEven {
  background-color: #c294fa;
}

.oddChild {
  background-color: #f2c4fa;
}

.evenChild {
  background-color: #d8bbfd;
}
<table>
  <tbody>
    <tr class="parentOdd">
      <td>Parent A</td>
    </tr>
    <tr class="oddChild">
      <td>A1</td>
    </tr>
    <tr class="oddChild">
      <td>A2</td>
    </tr>
    <tr class="parentEven">
      <td>Parent B</td>
    </tr>
    <tr class="parentOdd">
      <td>Parent C</td>
    </tr>
    <tr class="oddChild">
      <td>C1</td>
    </tr>
    <tr class="oddChild">
      <td>C2</td>
    </tr>
    <tr class="parentEven">
      <td>Parent D</td>
    </tr>
    <tr class="evenChild">
      <td>D1</td>
    </tr>
    <tr class="evenChild">
      <td>D2</td>
    </tr>
  </tbody>
</table>

I tried using CSS pseudo-selectors, but no luck.

.parent:nth-child(odd) {
  background-color: green;
}
.parent:nth-child(even) {
  background-color: blue;
}

The nth-child selector ignores the class. I tried using nth-of-type but that also ignored the class. And besides, both pseudo-selectors can't handle the case of the children.

Is what I'm trying to do possible in CSS? Or do I have to resort to JavaScript?

Jumbalaya Wanton
  • 1,601
  • 1
  • 25
  • 47
  • 1
    @Paulie_D This is clearly not a duplicate. Please retract your close vote. The other question does not address the nesting of children under parents. Something I have clearly explained in my question. Please consider reading the entire question before casting a close vote. Close votes are sometimes cast because there is an existing one, which leads to valid questions being wrongly closed. – Jumbalaya Wanton Feb 24 '15 at 15:43
  • I guess JS will be less tricky and can give you a faster solution – DaniP Feb 24 '15 at 15:45
  • 1
    I've removed the close vote although it remains my opinion that it is in fact a duplicate since the solution requires a re-structuring of the HTML. – Paulie_D Feb 24 '15 at 15:51
  • Is there a limit to how many children there will be? I could do it with CSS (sorta hackishly) if there's ever a limited number of children. – Chad Feb 24 '15 at 15:55
  • @Chad no, but it is certain to always be in the 10s. – Jumbalaya Wanton Feb 24 '15 at 16:18
  • @JumbalayaWanton I only went to the 2nd scale degree on this, but this is a crappy way to do it with CSS without changing your markup. http://jsfiddle.net/qjp4rt7u/ Basically you say `.parent` then any `.child` that directly follows it before reaching another parent. I've not come up with a way to style the children in one line of CSS, but this works if that's your only goal. – Chad Feb 24 '15 at 16:21
  • @Chad yeah, thanks! It looks like either multiple tbody tags or JS. – Jumbalaya Wanton Feb 24 '15 at 16:33

3 Answers3

7

Is there any reason not to use multiple <tbody>s?
Grouping rows can make it easy.

table {
  border-collapse: collapse;
  width: 100%;
}

td {
  border: 1px solid #eee;
  padding: 10px;
}

tbody:nth-child(odd) > tr { /* odd child */
  background-color: #f2c4fa;
}

tbody:nth-child(odd) > tr:nth-child(1) { /* odd parent */
  background-color: #eb94fa;
}

tbody:nth-child(even) > tr { /* even child */
  background-color: #d8bbfd;
}

tbody:nth-child(even) > tr:nth-child(1) { /* even parent */
  background-color: #c294fa;
}
<table>
  <tbody>
    <tr>
      <td>Parent A</td>
    </tr>
    <tr>
      <td>A1</td>
    </tr>
    <tr>
      <td>A2</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td>Parent B</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td>Parent C</td>
    </tr>
    <tr>
      <td>C1</td>
    </tr>
    <tr>
      <td>C2</td>
    </tr>
  </tbody>
  <tbody>
    <tr>
      <td>Parent D</td>
    </tr>
    <tr>
      <td>D1</td>
    </tr>
    <tr>
      <td>D2</td>
    </tr>
  </tbody>
</table>
taggon
  • 1,896
  • 13
  • 11
  • Even if this change the HTML structure, it's the less invasive change and the best option for a CSS solution +1 – DaniP Feb 24 '15 at 15:51
  • @Chad apparently it is possible to have multiple tbody elements in one table. See this: http://stackoverflow.com/questions/3076708/can-we-have-multiple-tbody-in-same-table – Jumbalaya Wanton Feb 24 '15 at 16:32
  • Good solution. Shame it makes the markup messy but at least its valid. _"The HTML Table Body Element () defines one or more rows as the body of its parent element when no elements are children of the parent."_ https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody
    – Moob Feb 24 '15 at 16:40
0

why not do some javascript?

var RowNumber = 0,

for(i = Rownumber + 1; i<=x*;i++) {
If (RowNumber % === 0) {
 this.setAttribute('class', 'even');
} else {
 this.setAttribute('class', 'odd');
}
});

create the even class and odd class and give each tr an id

*This is a note: Set x to equal the amount of rows in your table.

OR do a switch statement, I prefer a good ol' if statement but Switch could work just as well :)

HugoNumber1
  • 49
  • 10
0

Check this solution: http://fiddle.jshell.net/manzapanza/6vjLm0td/

table {
  border-collapse: collapse;
  width: 100%;
}

td {
  border: 1px solid #eee;
  padding: 10px;
}

.parentOdd {
  background-color: #eb94fa;
}
.parentOdd.child:nth-child(odd) {
  background-color: #F2C9F9;
}
.parentOdd.child:nth-child(even) {
  background-color: #F9E1DC;
}
.parentEven {
  background-color: #c294fa;
}
.parentEven.child:nth-child(odd) {
  background-color: #E1CCFC;
}
.parentEven.child:nth-child(even) {
  background-color: #EEE5FA;
}
<table>
  <tbody>
    <tr class="parentOdd">
      <td>Parent A</td>
    </tr>
    <tr class="parentOdd child">
      <td>A1</td>
    </tr>
    <tr class="parentOdd child">
      <td>A2</td>
    </tr>
    <tr class="parentEven">
      <td>Parent B</td>
    </tr>
    <tr class="parentOdd">
      <td>Parent C</td>
    </tr>
    <tr class="parentOdd child">
      <td>C1</td>
    </tr>
    <tr class="parentOdd child">
      <td>C2</td>
    </tr>
    <tr class="parentEven">
      <td>Parent D</td>
    </tr>
    <tr class="parentEven child">
      <td>D1</td>
    </tr>
    <tr class="parentEven child">
      <td>D2</td>
    </tr>
  </tbody>
</table>
manzapanza
  • 6,087
  • 4
  • 39
  • 48
  • 1
    I think he wants to emulate his example code by using only `.parent` and `.child`. – Chad Feb 24 '15 at 16:23