3

My problem is, I want to highlight the table row below of the row which I'm hovering currently.

However, the problem I'm facing is that after two rows it should then highlight the next two rows. Basically that every two rows of the table highlight as one.

So if rows 2 and 3 are being highlighted, when I hover over row 4 only 4 and 5 are being highlighted, 6 and 7 and so on.

Currently, on hover, it just highlights the row the mouse is on. Is something like this possible using CSS? Or have I just overlooked something obvious.

table tr:nth-child(4n+4) {
  background-color: #EBEBEB;
}
#table tr:nth-child(4n+5) {
  background-color: #EBEBEB;
}
#table tr:hover {
  background: #3498DB;
}

See my work here: http://jsfiddle.net/g5o7v6qe/21/

Sorry, if my question is a bit confusing or worded in a difficult manner, I do have some understanding of HTML and CSS but this for some reason stumped me. Thank you.

Yashwardhan Pauranik
  • 5,370
  • 5
  • 42
  • 65
MacGenius
  • 199
  • 4
  • 16
  • 1
    tr:hover, tr:hover + tr { background: #3498DB; } + What about the first and last? – VXp Sep 13 '18 at 06:37
  • what happens if you hover row 3? does it highlight row 2 or doesnt do anything ? – Chris Li Sep 13 '18 at 06:40
  • Using @VXp suggestion it works but oddly, so if row 2 is hovered on then both row 2 and 3 will highlight. If row 3 is hovered on then only row 3 is highlighted and the rows 4n+4 and 4n+5 are ignored completely from the hover. – MacGenius Sep 13 '18 at 06:47
  • You need to delete those and leave only the line I wrote. Remove: #table tr:nth-child(4n+4) {...} and #table tr:nth-child(4n+5) {...} – VXp Sep 13 '18 at 06:50
  • @VXp he's using adjacent sibling selector, it only selects an element behind of it, if you want something like hover row 3 and row 2 is highlighted i dont think it will work. there's no selecting previous element yet in css. – Chris Li Sep 13 '18 at 06:55
  • Okay I now understand what going on, but it's not quite what I want. So now it highlights 2 rows based on hover over row 1 - highlight row 1 and 2, hover over row 2 - highlight row 2 and 3. But is it possible to do something like hover over row 1 or 2 - highlight row 1 and 2 then hover over row 3 or 4 - highlight row 3 and 4 and so on? – MacGenius Sep 13 '18 at 06:58

5 Answers5

5

The solution you're searching for is sadly not possible with CSS alone, because CSS doesn't offer selectors for selecting preceding children (which you would need to also highlight the row above when hovering over the description). Instead, you could modify your HTML a bit to make this possible:

Introducing the tbody element !

The tbody element can used in conjunction with thead and tfoot to e.g. enable scrolling while locking the header and footer of the table in place. Also, when printing, the header and footer may get repeated on the next page, should the table span multiple pages. Check this question for more details.

What a lot of people don't know, is that you can have multiple tbody elements within a single table. That means you can wrap each group of rows in your table in a tbody element and then style each one appropriately:

#table {
  border-radius: 10px;
  border-collapse: collapse;
  width: auto;
}

#table td,
#table th {
  border: 1px solid #DDDDDD;
  padding: 8px;
}

#table th {
  padding-top: 12px;
  padding-bottom: 12px;
  text-align: center;
  background-color: #333333;
  color: white;
}

#table tbody:nth-child(2n+3) {
  background-color: #EBEBEB;
}

/* Group highlights */
#table tbody:hover {
  background: #3498D8;
}
<table align="center" id="table">
  <thead>
    <tr>
      <th>Vendor</th>
      <th>Model</th>
      <th>Year</th>
      <th>Source</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>vendor1</td>
      <td>model1</td>
      <td>year1</td>
      <td>source1</td>
    </tr>
    
    <tr>
      <td colspan="4">description1</td>
    </tr>
  </tbody>

  <tbody>
    <tr>
      <td>vendor2</td>
      <td>model2</td>
      <td>year2</td>
      <td>source2</td>
    </tr>
    
    <tr>
      <td colspan="4">description2</td>
    </tr>
  </tbody>

  <tbody>
    <tr>
      <td>vendor3</td>
      <td>model3</td>
      <td>year3</td>
      <td>source3</td>
    </tr>
    
    <tr>
      <td colspan="4">description3</td>
    </tr>
  </tbody>

  <tbody>
    <tr>
      <td>vendor4</td>
      <td>model4</td>
      <td>year4</td>
      <td>source4</td>
    </tr>
    
    <tr>
      <td colspan="4">description4</td>
    </tr>
  </tbody>
</table>

P.s.: While you're at it, you might also want to nest your table header in a thead element for the sake of consistency.

MacGenius
  • 199
  • 4
  • 16
Tobias Meister
  • 175
  • 2
  • 10
  • Thank you that works perfectly, 100% and is what I was trying to achieve. I have accepted your answer, and thank you to everyone else who has contributed. – MacGenius Sep 13 '18 at 10:00
  • Any down sides of adding lots of tbody in your table? – Persijn Sep 13 '18 at 10:44
  • @Persijn not that I know of. Only thing I can think of is that they should all be in consecutive order. Utilizing multiple tbody tags is also described on MDN https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody#Multiple_bodies – Tobias Meister Sep 13 '18 at 10:54
2

So in my understanding you want it like that: jsfiddle

#table tr:nth-child(2n+2):hover {
  background: #3498DB;
}

#table tr:nth-child(2n+2):hover + tr {
  background: #3498DB;
}

Starting at the second row with nth-child(2n+2) it highlights every 2 rows on hover.

With + tr you achieve that all tr that are an adjacent sibling of an hovered tr get highlighted.

Hope that makes sense to you.

EDIT: Notice that this works not for hovering the 2nd row of each row group to highlight the group. So this is not a - full - solution to the Problem.

janDo
  • 23
  • 3
  • the only thing that's missing is when you hover over the second row of a pair it won't highlight the group. – Brian H. Sep 13 '18 at 07:34
1

Javascript table highlight

Css does not let you selected a sibling upwards in the dom.

Here is how i would solve it in JS:

$(function() {
  //Selected all rows with a data-group attribute
  let rows = $("tr[data-group]");
  //on hover over 
  rows.hover(function over() {
    let group = $(this).data("group");
    $(this).addClass("highlight");
    $(this).siblings("tr[data-group=" + group + "]").addClass("highlight");
    //on hover out
  }, function out() {
    let group = $(this).data("group");
    $(this).removeClass("highlight");
    $(this).siblings("tr[data-group=" + group + "]").removeClass("highlight");
  });
});
table {
  border: 1px solid black;
}

td {
  padding: 0.5em 1em;
  border: 2px solid blue;
}

.highlight {
  background-color: cornflowerblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr data-group="1">
    <td>element1</td>
    <td>element2</td>
  </tr>
  <tr data-group="1">
    <td colspan="2">Long element</td>
  </tr>
  <tr data-group="2">
    <td>element1</td>
    <td>element2</td>
  </tr>
  <tr data-group="2">
    <td colspan="2">Long element</td>
  </tr>
  <tr data-group="3">
    <td>element1</td>
    <td>element2</td>
  </tr>
  <tr data-group="3">
    <td colspan="2">Long element</td>
  </tr>
  <tr data-group="4">
    <td>element1</td>
    <td>element2</td>
  </tr>
  <tr data-group="4">
    <td colspan="2">Long element</td>
  </tr>
</table>
Persijn
  • 14,624
  • 3
  • 43
  • 72
0

Is this what you would like to achieve?

Also I've revised the incorrect html markup and css.

#table {
  border-radius: 10px;
  border-collapse: collapse;
  width: auto;
}

#table td,
#table th {
  border: 1px solid #DDDDDD;
  padding: 8px;
}

#table tr:nth-child(4n+3) {
  background-color: #EBEBEB;
}

#table tr:nth-child(4n+4) {
  background-color: #EBEBEB;
}

#table tr:hover td,
#table tr:nth-child(2n+1):hover td,
#table tr:nth-child(2n+1):hover + tr td {
  background: #3498DB;
}

#table th {
  padding-top: 12px;
  padding-bottom: 12px;
  text-align: center;
  background-color: #333333;
  color: white;
}
<table align="center" id="table">
  <thead>
    <tr>
      <th>Vendor</th>
      <th>Model</th>
      <th>Year</th>
      <th>Source</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>vendor1</td>
      <td>model1</td>
      <td>year1</td>
      <td>source1</td>
    </tr>
    <tr>
      <td colspan="4">description1</td>
    </tr>
    <tr>
      <td>vendor2</td>
      <td>model2</td>
      <td>year2</td>
      <td>source2</td>
    </tr>
    <tr>
      <td colspan="4">description2</td>
    </tr>
    <tr>
      <td>vendor3</td>
      <td>model3</td>
      <td>year3</td>
      <td>source3</td>
    </tr>
    <tr>
      <td colspan="4">description3</td>
    </tr>
    <tr>
      <td>vendor4</td>
      <td>model4</td>
      <td>year4</td>
      <td>source4</td>
    </tr>
    <tr>
      <td colspan="4">description4</td>
    </tr>
  </tbody>
</table>
Chaska
  • 3,165
  • 1
  • 11
  • 17
  • Oh thank you @Chaska that is great! That is what I was wanting. Is it maybe possible that when the description is highlight it also highlights the above row? If not no worries. – MacGenius Sep 13 '18 at 07:15
  • Don't think it's possible to be done with pre css. Btw I've revised the code and there's no need to add extra class name. – Chaska Sep 13 '18 at 07:26
  • @MacGenius You can't, you can do one thing, but it fails with the other. You can highlight the desc. and it will highlight the associated one, but when vice versa it will just highlight the one after it in the DOM. I'm talking about flexbox/grid and the order property. http://jsfiddle.net/g5o7v6qe/80/ Not possible atm., i.e. can't go up, yet... – VXp Sep 13 '18 at 07:32
  • No worries I understand now why it won't work the way I would like it to, but still thank you all for the help. – MacGenius Sep 13 '18 at 07:54
0

Below is the code for highlighting the next two row in a table when we hover on a particular row.

td, th {
  padding: 10px;
}
tr.head-row {
  background: grey;
}
tr:not(.head-row) {
  background: #fff5f5;
}


/* highlight the current row on hover*/
tr:hover:not(.head-row) {
    background: #f8b5b5;
}

/* highlight next row on hovering a row */
tr:hover:not(.head-row) + tr {
    background: #91cefe;
}

/* highlight next to next row on hovering a row */
tr:hover:not(.head-row) + tr + tr {
    background: #67ace1;
}
<table style="width:100%" id="table">
  <tr class="head-row">
    <th>Firstname</th>
    <th>Lastname</th>
    <th>Age</th>
  </tr>
  <tr>
    <td>Jill</td>
    <td>Smith</td>
    <td>50</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Eveas</td>
    <td>Jackson we</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Everrr</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Eve ff</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Eve</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Eveas</td>
    <td>Jackson we</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Everrr</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
  <tr>
    <td>Eve ff</td>
    <td>Jackson</td>
    <td>94</td>
  </tr>
</table>
Dipak
  • 6,532
  • 8
  • 63
  • 87