csshtml-tablez-indexbox-shadow

How to overlap box-shadows on table rows?


I have a table on which I want to highlight a number of successive rows (TR's) by applying a box-shadow around them.

My strategy was to apply a class called "selected-top" to the first row of the selection, classes "selected-middle" for the middle part, and "selected-bottom" for the last row.

However, the shadows of the middle rows bleed over. I tried to rectify this by using z-index (I know that I have to add a relative property with that, so I did), but they seem to have no effect:

enter image description here

Here's the code:

  tr.selected-top {
    box-shadow: -5px -5px 5px #000, 5px -5px 5px #000;
    position: relative;
    z-index:10;
  }
  tr.selected-middle {
    box-shadow: -5px 0px 5px #000, 5px 0px 5px #000;
    position: relative;
    z-index: -1;
  }

The table is just a regular table:

<table>
<tr><td>stuff</td></tr>
<tr class="selected-top"><td>highlighting starts</td></tr>
<tr class="selected-middle"><td>highlighting middle</td></tr>
<tr class="selected-bottom"><td>highlighting end</td></tr>
<tr><td>other stuff</td></tr>
</table>

What am I doing wrong?

By the way, I did try to only apply a shadow to only the sides for the middle rows, but that way the shadow is not continuous.

Update: @Aditya Toke, like so: (left is wrong shading, right is correct shading) enter image description here


Solution

  • You can achieve it using ::before and ::after pseudo elements to mask the top and bottom shadow from "middle" row.

    The height of the pseudo elements is set exactly equal to the length of the shadow for masking and is absolute position.

    Since the shadow hides the top borders of selected-bottom and it's next sibling element we need to add them back as:

    tr.selected-middle td,
    tr.selected-bottom td {
      border-bottom: 1px solid #666;
    }
    

    body {
      background-color: #1b1b1b;
      margin: 20px;
    }
    table {
      font-family: arial, sans-serif;
      border-collapse: collapse;
      width: auto;
      box-sizing: border-box;
      border: none;
      margin: auto;
    }
    
    tr { display: block; }
    tr, td {
      height: 50px;
      background: #333;
      color: #eee;
    }
    
    td {
      padding-left: 16px;
      min-width: 170px;
      width: 100%;
      border-top: 1px solid #666;
    }
    tr.selected-top {
        position: relative;
        box-shadow: -5px -5px 5px #000, 5px -5px 5px #000;
    }
    tr.selected-middle {
        position: relative;
        box-shadow: 0px 0px 5px 5px #000;
    }
    tr.selected-bottom {
        position: relative;
        box-shadow: 5px 5px 5px #000, -5px 5px 5px #000;
        
    }
    tr.selected-middle ::before,
    tr.selected-middle ::after {
        pointer-events: none;
        position: absolute;
        content:" ";
        background-color: #333;
        left: 0;
        width: 100%;
    }
    tr.selected-middle ::before {
        height: 10px;
        top: -10px;
    }
    tr.selected-middle ::after {
        top: calc(100% + 4px);
        height: 5px;
    }
    
    tr.selected-middle td,
    tr.selected-bottom td {
      border-bottom: 1px solid #666;
    }
    <table>
      <tbody>
        <tr>
            <td>Some stuffs</td>
        </tr>
        <tr class="selected-top">
            <td>highlighting starts</td>
        </tr>
        <tr class="selected-middle">
            <td>highlighting middle</td>
        </tr>
        <tr class="selected-bottom">
            <td>highlighting ends</td>
        </tr>
         <tr>
            <td>Some stuffs</td>
        </tr>
      </tbody>
    </table>