Search code examples
cssbordercss-tables

How to fix z-index of table rows when using transform: scale();


In a table, I'd like to scale rows with borders on hover. However, the scaled row keeps on being in the background instead of in the foreground. I noticed, that this only happens in tables, not with list-tags (can't change the html though).

I tried a lot of different CSS techniques but none of them seem to work. Like border-collapse, z-index etc. Also targeting the td instead of the tr doesn't work. Edit: using position: absolute breaks the table layout.

tr {
  transition: all 0.24s;
  transform: scale(1);
}

tr:hover {
  transform: scale(1.03);
  z-index: 10;
}

<normal table html layout table, tbody, tr, td>

The screenshot shows the actual result – The hovered row stays behind the other rows hence the thinner borders. The expected result should show the full 1px border in front of the other rows' borders.

http://jsfiddle.net/djpcgmn0/


Solution

  • The problem is not that the row is displayed beneath the other rows in the z-index, but that border-collapse prevents the borders in the zoomed row from being drawn correctly.
    You can see the problem more clearly if you use transform: scale(2) or something when zooming, then the overlap is obvious.

    So the solution is to not use border-collapse: collapse.
    That's basically it. If you also want the borders to look the same as in your fiddle, you will need some more CSS, but that's not the issue.

    table {
      border-spacing: 0;
      /*border-collapse: collapse;*/  /* not used */
      table-layout: fixed;
    }
    
    tr {
      transition: all 1s;
    }
    
    tr:hover {
      transform: scale(1.1)
    }
    
    td {
      background: grey;
      border-bottom: 2px solid lightgreen;
      border-right: 2px solid white;
    }
    
    /* new from here */
    
    tr:first-child td, tr:hover td {
      border-top: 2px solid lightgreen;
    }
    
    td:first-child {
      border-left: 2px solid white;
    }
    <table>
      <tbody>
        <tr>
          <td>Row 1 data cell 1</td>
          <td>Row 1 data cell 2</td>
          <td>Row 1 data cell 3</td>
        </tr>
        <tr>
          <td>Row 2 data cell 1</td>
          <td>Row 2 data cell 2</td>
          <td>Row 2 data cell 3</td>
        </tr>
        <tr>
          <td>Row 3 data cell 1</td>
          <td>Row 3 data cell 2</td>
          <td>Row 3 data cell 3</td>
        </tr>
      </tbody>
    </table>