6

Changing the background color of a row in a table on mouse over is pretty simple using CSS:

.HighlightableRow:hover
{
  background-color: lightgray;
}

And some HTML:

<table>
  <tr class=HighlightableRow>
    <td>Cell 1</td>
    <td>Cell 2</td>
    <td>Cell 3</td>
  <tr>
  <tr class=HighlightableRow>
    <td>Cell 1</td>
    <td>Cell 2</td>
    <td>Cell 3</td>
  <tr>
</table>

Occasionally, I want to highlight a pair of rows when I hover my mouse over either of them. For example, when displaying a list of work orders in a table, I would have one row with the creator, date created, urgency, etc. and the second row would have an except of the work that was requested.

Is there any way, other than using the JavaScript onmouseover/onmouseout event handlers, to create this effect like the one shown above? Preferably using CSS.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sparafusile
  • 4,696
  • 7
  • 34
  • 57

3 Answers3

22

Use the tbody element to group rows.

tbody:hover { background:#eee;}

HTML:

<table>
  <tbody>
    <tr>
      <td>Hello</td>
      <td>World!</td>
    </tr>
    <tr>
      <td>Hello</td>
      <td>World!</td>
    </tr>
  </tbody>
</table>

Check out the details about "tbody", "thead" and "tfoot" for the correct usage.

Chris
  • 215
  • 2
  • 4
  • This highlights *all* rows, not just two. –  Oct 28 '12 at 12:50
  • 4
    You can have more than one tbody in a table. If there are exactly two rows in each tbody, his solution will work. See: http://stackoverflow.com/questions/3076708/can-we-have-multiple-tbody-in-same-table – Sparafusile Oct 28 '12 at 13:41
10

This is actually pretty simple to do, if you are content with highlighting the next row.

tr:hover, tr:hover + tr {
background:#eee; }

The css + selector merely selects the immediatly following element, if it matches your type. So in this case, it highlights the current row, plus the next row.

See jsFiddle

Of course, there are limitations, if you want to group two, as you cannot do "this row, and the previous". In that case, I would probably nest the two rows in a new table, inside the first row. Make sense?

EDIT: something like this

HTML

<table>
     <tr>
       <td>

         <table>

           <tr>
             <td>Hello</td>
             <td>World!</td>
           </tr>

           <tr>
             <td>Hello</td>
             <td>World!</td>
           </tr>

         </table>

       </td>
     </tr>
   </table>

CSS

tr:hover tr { background:#eee; }

Working fiddle

Nix
  • 5,746
  • 4
  • 30
  • 51
  • Could you use the + selector on the first row to highlight the second and - on the second row to highlight the first? That pretty much mimics what I'm doing with JavaScript right now. – Sparafusile Jan 06 '12 at 19:50
  • Sadly, no. It goes only one way, as CSS has no way of selection the previous element. But you can put a new table inside a tr, and highlight that. Look at my updated fiddle: http://jsfiddle.net/6TYBb/1/ – Nix Jan 06 '12 at 20:01
  • 1
    @Martin No. Due to the way CSS works, you can not select previous or parent element. This might seem silly, but it makes a lot of sense from a perfomance POV. Johnathan Snook has written an excellent article on it: http://snook.ca/archives/html_and_css/css-parent-selectors/ The only sane way to do this, without resorting to JavaScript violence, is by nesting, as I illustrate in the Fiddle above. When you hover any of the two bottom rows, they are both highlighted, because the `:hover` targeting is on the parent element itself. I hope that makes sense. – Nix Jul 31 '12 at 15:50
  • sadly, this doesn't allow for grouping, and adding a table inside a tr will throw off alignment of the columns. – Mike A. Nov 06 '19 at 13:08
1

I don't know of a way to cause events on one object to interact with another object in vanilla CSS. Generally, when you want to wire up such custom events you are stuck using some sort of actual logical programming language (in this case javascript).

Now, if you do decide to go that route, I can help you with some very simple jQuery to do exactly what you need :). jQuery's event binding model actually takes a lot of the pain out of javascript.

Sheridan Bulger
  • 1,214
  • 7
  • 9
  • Thanks for the answer. I actually like the pain of JavaScript, but I'll start a new question if I change my opinion. – Sparafusile Jan 06 '12 at 19:32