-2

I created the following code. In this case, we thought that tr:nth-child(odd) works as follows

  1. caption-> not tr
  2. tr-> not odd
  3. tr-> background red!
  4. tr-> not odd
  5. tr-> background red!

But this worked this way

  1. caption-> not tr
  2. tr-> no background red
  3. tr-> no background red
  4. tr-> background red!
  5. tr-> no background red

table {
  border-collapse: collapse;
  color: #000000;
  width: 80%;
}

td,
th {
  border: 1px solid #000000;
  background-color: rgba(0, 0, 0, 0.3);
  text-align: center;
  padding: 3px;
}

th {
  background-color: #31A9EE;
}

tr:nth-child(odd) {
  background: red;
}
<table border="1">
  <caption>caption</caption>
  <tr>
    <th>head1</th>
    <th>head2</th>
    <th>head3</th>
  </tr>
  <tr>
    <td>1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>2</td>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>3</td>
    <td>3</td>
  </tr>
</table>

Why does nth-child not work as desired? I want to do this:

table {
  border-collapse: collapse;
  color: #000000;
  width: 80%;
}

td,
th {
  border: 1px solid #000000;
  background-color: rgba(0, 0, 0, 0.3);
  text-align: center;
  padding: 3px;
}

th {
  background-color: #31A9EE;
}

tr:nth-child(odd) {
  background: red;
}
<table border="1">
  <caption>caption</caption>
  <tr>
    <th>head1</th>
    <th>head2</th>
    <th>head3</th>
  </tr>
  <tr style="background: red;">
    <td>1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr  style="background: transparent;">
    <td>2</td>
    <td>2</td>
    <td>2</td>
  </tr>
  <tr  style="background: red;">
    <td>3</td>
    <td>3</td>
    <td>3</td>
  </tr>
</table>
TylerH
  • 20,799
  • 66
  • 75
  • 101
Ree Chung
  • 1
  • 1
  • 1
    Welcome to Stack Overflow! Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. – Paulie_D Mar 09 '20 at 13:35
  • 1
    It's working fine, since you defined `th` background colour, it covered the `tr` background colour in your first row, remove the `th` rule and you will see. By the way you have coded this, you can just use even instead of odd – Huangism Mar 09 '20 at 13:36
  • i want to apply bg-color to row 1 and 3. but now it is apply to only row 2. – Ree Chung Mar 09 '20 at 13:36
  • 1
    @ReeChung you can edit your own question to add what you said in comments so it is clear to everyone what you are trying to do, but my comment explains everything you need to know – Huangism Mar 09 '20 at 13:39
  • 1
    in HTML your first row is actually row with the `th` elements. NOT the one with `td` – MonteCristo Mar 09 '20 at 13:39
  • @MonteCristo I'm dealing with tr, so td and th have no CSS – Ree Chung Mar 09 '20 at 13:42
  • 2
    @ReeChung you have css `th { background-color: #31A9EE; }` and this `background-color: rgba(0, 0, 0, 0.3);` these styles are overriding the 1st row background styles. you need to change `odd` to `even` – MonteCristo Mar 09 '20 at 13:45

3 Answers3

1

I want to apply bg-color to row 1 and 3

Because the first tr is not an odd child...its the second child...and so on.

What you actually need is

tr:nth-of-type(even){
  background: red;
}

to target the 2nd tr etc....

table {
  border-collapse: collapse;
  color: #000000;
  width: 80%;
}

td,
th {
  border: 1px solid #000000;
  background-color: rgba(0, 0, 0, 0.3);
  text-align: center;
  padding: 3px;
}

th {
  background-color: #31A9EE;
}

tr:nth-of-type(even){
  background: red;
}
<table border="1">
  <caption>caption</caption>
  <tr>
    <th>First tr</th>
    <th>First tr</th>
    <th>First tr</th>
  </tr>
  <tr>
    <td>1</td>
    <td>1</td>
    <td>1</td>
  </tr>
  <tr>
    <td>2</td>
    <td>2</td>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>3</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>4</td>
    <td>4</td>
  </tr>
</table>
Paulie_D
  • 107,962
  • 13
  • 142
  • 161
  • While this works but the reason OP's original code didn't look like it worked is because of the `th` background colour – Huangism Mar 09 '20 at 13:46
  • is tr row 1 odd child, right? – Ree Chung Mar 09 '20 at 13:49
  • @ReeChung Yes tr row 1 is odd, but you have `th` background colour which is on top of your `tr` so you don't get red color. I have already demonstrated this in my answer but it seems you are confused by it so I removed it – Huangism Mar 09 '20 at 13:52
0

Even if you write the tr element directly in thetable element, the HTML processing will interpret that there is a tbody element under thetable element and that there is a tr element in it. On the other hand, the caption element is placed just below thetable element.

Therefore, tr:nth-child(odd) doesn't count the caption element which is not a sibling of the tr element.

So why is the tbody element inserted even though the tr element is allowed directly under the table? For historical reasons, the tbody element wasn't omissible in the HTML4 era, and tr element didn't come directly under table element. This means that there is a tbody element without writing a tag.

11.2.3 Row groups: the THEAD, TFOOT, and TBODY elements

TFOOT must appear before TBODY within a TABLE definition so that user agents can render the foot before receiving all of the (potentially numerous) rows of data. The following summarizes which tags are required and which may be omitted:

  • The TBODY start tag is always required except when the table contains only one table body and no table head or foot sections. The TBODY end tag may always be safely omitted.
  • The start tags for THEAD and TFOOT are required when the table head and foot sections are present respectively, but the corresponding end tags may always be safely omitted.

Conforming user agent parsers must obey these rules for reasons of backward compatibility.

For this reason, it seems that even today, with the spread of HTML5, major browsers supplement the tbody element even without a tag.

You can use tr:nth-child(even) instead of tr:nth-child(odd).

table {
  border-collapse: collapse;
  color: #000000;
  width: 80%;
}

td,
th {
  border: 1px solid #000000;
  background-color: rgba(0, 0, 0, 0.3);
  text-align: center;
  padding: 3px;
}

th {
  background-color: #31A9EE;
}

tr:nth-child(even) {
  background: red;
}
<table border="1">
  <caption>caption</caption>
  <tr>
    <th>head1</th>
    <th>head2</th>
    <th>head3</th>
  </tr>
  <tr>
    <td>1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>2</td>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>3</td>
    <td>3</td>
  </tr>
</table>
sanriot
  • 804
  • 4
  • 13
  • This has nothing to do with the tbody, only reason the odd didn't seem to work is because of the OP's `th` background colour – Huangism Mar 09 '20 at 13:55
  • @Huangism Wrong; you can inspect OP's code in the browser and see a `` wrapper is (properly) inserted around the `` elements, changing the `nth` order of the elements. This is the correct answer. – TylerH Mar 09 '20 at 14:04
  • @TylerH tbody wraps all tr, first odd tr would be the th row which works but the th row is covered by the th background color. The OP thinks the odd didn't work due to it, with the way it is coded, using even solves the issue but odd works as is and there is nothing wrong with that, it has to do with tbody – Huangism Mar 09 '20 at 14:09
0

change odd to even or change html to this

<table border="1">
  <caption>caption</caption>
  <thead>
  <tr>
    <th>head1</th>
    <th>head2</th>
    <th>head3</th>
  </tr>
  </thead>

  <tr>
    <td>1</td>
    <td>1</td>
    <td>2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>2</td>
    <td>2</td>
  </tr>
  <tr>
    <td>3</td>
    <td>3</td>
    <td>3</td>
  </tr>
</table>
Nazeeh
  • 45
  • 1
  • 10