0

I thought I was reasonably versed in CSS, but this one has me stumped.

How do you target the topmost row of a table, if you don't know what the table structure is? My CSS file needs to be independent of however the HTML is structured.

So what is the selector I should use? If the table has a thead, then it's easy.

.theTable > thead > tr:first-child {..}

and if it only has one or more tbody elements, that's easy too.

.theTable > tbody:first-of-type > tr:first-child {..}

but if you don't know? How do you prevent ending up styling both the thead and the tbody?

For example, how do you make sure that in the following three tables, only the top row in each one gets the style?

/* bad CSS */
table tr:first-of-type {background:tan;}
<table>
 <thead><tr><th>nr</th><th>name</th></thead>
 <tbody><tr><td>1</td><td>one</td>
        <tr><td>2</td><td>two</td></tbody>
</table>
<hr>
<table>
 <tbody><tr><td>1</td><td>one</td>
        <tr><td>2</td><td>two</td></tbody>
</table>
<hr>
<table>
 <caption>names</caption>
 <tbody><tr><td>1</td><td>one</td>
        <tr><td>2</td><td>two</td></tbody>
</table>
Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • 2
    `table tr:first-of-type`? Can you post some more complete examples of what isn't working, specifically the HTML? – j08691 Aug 24 '22 at 16:27
  • 1
    @j08691 `first-of-type` means the first of this type IN ITS PARENT. So if a table has a thead and two tbodies, each of these three elements has a `first-of-type` tr. In elements that can contain only one certain type of children (like these), `first-of-type` means exactly the same as `first-child`. – Mr Lister Aug 24 '22 at 16:53
  • And I can post some examples, but I'm afraid that the answers will only concentrate on those specific examples, without actually solving the problem. – Mr Lister Aug 24 '22 at 16:54
  • 1
    I think you'd have to select the first tbody and thead and then reset styles on the tbody if it existed. Something like the answer here https://stackoverflow.com/a/41545694/616443 – j08691 Aug 24 '22 at 17:33
  • 1
    @j08691 Thanks for that link! I did search before posting, but apparently not good enough. – Mr Lister Aug 24 '22 at 17:50
  • And one of the answers there helped me out exactly, so this one can be closed. – Mr Lister Aug 25 '22 at 04:59

1 Answers1

0

As @j08691 said, could you not use tr:first-of-type?

Edit: This is super tricky due to the way CSS cascades, and the nesting specifically, but I think what your looking for is the following? (Though I think you'll need to override cases like the second table.

table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 80%;
  margin: 0 auto;
}

td,
th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}

thead {
  border: 2px solid #f00;
}

tbody {
  border: 2px solid #0f0;
}

tfoot {
  border: 2px solid #00f;
}


/* Top most row regardless of table structure. */

table > tbody > tr:first-child {
  color: #f0f;
}
<table>
  <thead>
    <tr>
      <th>Month</th>
      <th>Savings</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>January</td>
      <td>$100</td>
    </tr>
    <tr>
      <td>February</td>
      <td>$80</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>Sum</td>
      <td>$180</td>
    </tr>
  </tfoot>
</table>

<br/>

<table>
  <tr>
    <td>Foo</td>
    <td>ABC</td>
  </tr>
  <tr>
    <td>Bar</td>
    <td>DEF</td>
  </tr>
  <tbody>
    <tr>
      <td>Alex</td>
      <td>Lucy</td>
    </tr>
    <tr>
      <td>Mira</td>
      <td>Dave</td>
    </tr>
  </tbody>
</table>

<br/>

<table>
  <caption>Table stuff...</caption>
  <tr>
    <td>Test 1</td>
    <td>Awesome</td>
  </tr>
  <tr>
    <td>Test 2</td>
    <td>Cool</td>
  </tr>

  <tfoot>
    <tr>
      <td>Conclusion</td>
      <td>Erm what?</td>
    </tr>
  </tfoot>
</table>
Lewis
  • 1,945
  • 5
  • 26
  • 52