4

I have a table.

enter image description here

It currently contains a thead, tbody, and tfoot section.

I want to target the last row (tr) in the table.

If I use tr:last-of-type, it causes 3 rows to be targeted:

enter image description here

This is because it targets the last tr in the thead, the last tr in the tbody, and the last tr in the tfoot.

I don't want it to target 3 rows. I only want it to target the last row in the table.

I can use tfoot tr:last-of-type, which will work as long as tfoot has at least one tr element in it:

enter image description here

However, if the tfoot is empty, or if the table lacks a tfoot element, then nothing will be targeted.

I want to always target the absolute last row of the table, using only CSS. How can I do that?

Pikamander2
  • 7,332
  • 3
  • 48
  • 69

4 Answers4

3

One simple way to 'always target the last row, not matter where it is' is simply

table > *:last-child > tr:last-of-type {
 background-color: #0f0;
}
<table>
 <thead>
  <tr>
   <th>A</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>a</td>
  </tr>
  <tr>
   <td>b</td>
  </tr>
 </tbody>
</table>

<table>
 <thead>
  <tr>
   <th>A</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>a</td>
  </tr>
  <tr>
   <td>b</td>
  </tr>
 </tbody>
 <tfoot>
  <tr>
   <td>c</td>
  </tr>
 </tfoot>
</table>

This will do what you described, though there is a catch. The order of the <thead>, <tbody> and <tfoot> elements is not enforced, so you may actually put a <tfoot> before the <tbody> with the same table as output, in which case literally the last <tr> will get selected, which is not visually the last <tr>.

That would require some additional trickery:

/* the optimistic true last <tr> */
table > :last-child > tr:last-of-type,
/* any last <tr> within a <tfoot> */
table tfoot > tr:last-of-type {
    background-color: #0f0;
}

/* reset any style in the true last <tr> if its parent is
   preceded by a `<tfoot>` */
table > tfoot ~ :last-child > tr:last-of-type {
    background-color: initial;
}

working fiddle

EDIT: I forgot to take empty <tfoot> element into consideration, this demands the use of the :not and :empty pseudo classes (which are not supported by older browsers), which would look like:

/* the optimistic true last <tr> */
table > :last-child > tr:last-of-type,
/* any last <tr> within a <tfoot> */
table tfoot > tr:last-of-type {
    background-color: #0f0;
}

/* reset any style in the true last <tr> if its parent is
   preceded by a `<tfoot>` */
table > tfoot:not(:empty) ~ :last-child > tr:last-of-type {
    background-color: initial;
}

updated fiddle

Rogier Spieker
  • 4,087
  • 2
  • 22
  • 25
  • Wow, that looks really promising. I'll take a closer look later to see if it meets all of the edge cases. – Pikamander2 Sep 15 '16 at 22:46
  • I think that the problem is the same. If the last `tr` is empty, it fails – Iván Rodríguez Torres Sep 15 '16 at 22:50
  • @IvanRodriguezTorres - You're right, it fails here: https://jsfiddle.net/10tLbtsk/ – Pikamander2 Sep 15 '16 at 22:53
  • While you are correct @IvanRodriguezTorres that this will do nothing visually for the last `` if this is empty, it will target its style. The requirement stated nothing about the last `` being empty (which cannot be done by CSS), it does however state that an empty `` should be disregarded, which is now added to the answer. – Rogier Spieker Sep 15 '16 at 23:17
  • This does not fix the issue with an empty `` after ``, though that can probably be easily worked around by always using the order: thead, tfoot, tbody. The main reason with this not being possible with pure CSS lies in the fact that CSS only goes 'forward' (an empty tfoot after a tbody can be targeted (`tbody + tfoot:empty`) but in this case you'd want to actually target the `tbody` in there, which cannot be done (unfortunately not even with something like `tbody:not(+ tfoot:empty)`, as the `not` pseudo-class only allows 'simple selectors' which rule out sibling relations (`+`) – Rogier Spieker Sep 15 '16 at 23:36
2

Another way here.

table
{
   border-collapse:collapse;
}
tr{
   border-bottom: 1px solid #000;
}

table :last-child >:last-child > td {
   background-color: red
}
<table>
  <tr>
<td>a
</td>
<td>a
</td>
  </tr>
  <tr>
<td>b
</td>
<td>b
</td>
  </tr>
  <tr>
<td>v
</td>
<td>v
</td>
  </tr>
</table>
--------------
<table>
  <tr>
<td>a
</td>
<td>a
</td>
  </tr>
  <tr>
<td>b
</td>
<td>b
</td>
  </tr>
  <tr>
<td>v
</td>
<td>v
</td>
  </tr>
  <tfoot>
<tr>
  <td>v
  </td>
  <td>v
  </td>
</tr>
  </tfoot>
</table>
------------

<table>
  <thead>
<tr>
  <td>r</td>
  <td>r</td>
</tr>
  </thead>
  <tr>
<td>a
</td>
<td>a
</td>
  </tr>
  <tr>
<td>b
</td>
<td>b
</td>
  </tr>
  <tr>
<td>v
</td>
<td>v
</td>
  </tr>
  <tfoot>
<tr>
  <td>v
  </td>
  <td>v
  </td>
</tr>
  </tfoot>
</table>

solution is easy. First you adress the table, in my snippet table. Then you have to address the very last element, and as we have three leveles (thead or tbody or tfoot > td > 'tr') we need to address the last element 3 times

Iván Rodríguez Torres
  • 4,293
  • 3
  • 31
  • 47
1

Not sure what you mean by target the last row in the table.

If you want to target the last tfoot you would use:

 table tfoot tr:last-of-type

If you want to target the last row in the tbody you would use:

table tbody tr:last-of-type

If you want to target the last row in the thead you would use:

table thead tr:last-of-type

If you want to target the last row in the tfoot unless it's empty as which point you want to target the last row in the tbody then you will need to use JavaScript.

Here is a fiddle link for you to see the code. Fiddle Link

Crystal
  • 148
  • 1
  • 7
  • I'm looking for the last thing that you said, but with a pure CSS solution instead of JavaScript. – Pikamander2 Sep 15 '16 at 22:44
  • CSS doesn't support conditional statements. [CSS if else] or [CSS if](http://stackoverflow.com/questions/2446812/css-equivalent-of-the-if-statement). Not sure how helpful that is – Crystal Sep 23 '16 at 02:08
0

Completely editing my answer. Sorry about that. The issue here is that you just can't tell if the last row has any content with CSS.

So purely using CSS is not going to work because the row still exists even if it's empty. So it'll be styling the last row, there will just be nothing in it. I'd look to Javascript or if you're generating this sever side add a class to the last row so you can custom style it.

Michael Heath
  • 174
  • 2
  • 11
  • I just realized I may have missed what you were saying. One moment! – Michael Heath Sep 15 '16 at 22:16
  • Correct, this doesn't address the last part of the question. I want to always target the last row, no matter where it is. Basically, I want a one-size-fits-all solution. – Pikamander2 Sep 15 '16 at 22:20