Box Shadow on table row not appearing on certain browsers
Asked Answered
H

11

46

CSS box-shadow on table rows - tr - doesn't seem to be working consistently across browsers. On some browsers the shadow is displayed; on others, there is no shadow.

I'm using the following CSS:

tr {
  background-color: rgb(165, 182, 229);
  box-shadow: 0px 2px 2px black;
  -moz-box-shadow: 0px 2px 2px black;
  -webkit-box-shadow: 0px 2px 2px black;
}
td, th {
  padding: 5px;
  text-align: left;
}

Here is a jsFiddle of the below snippet:

tr {
  background-color: rgb(165, 182, 229);
  box-shadow: 0px 2px 2px black;
  -moz-box-shadow: 0px 2px 2px black, ;
  -webkit-box-shadow: 0px 2px 2px black;
}
td, th {
  padding: 5px;
  text-align: left;
}
<table>
  <tr>
    <td>&nbsp;</td>
    <th>One</th>
    <th>Two</th>
  </tr>
  <tr>
    <th>Title</th>
    <td>Three</td>
    <td>Four</td>
  </tr>
  <tr>
    <th>Title2</th>
    <td>Five</td>
    <td>Six</td>
  </tr>
  <tr>
    <th>Title3</th>
    <td>Seven</td>
    <td>Eight</td>
  </tr>
  <tr>
    <th>Title4</th>
    <td>Nine</td>
    <td>Ten</td>
  </tr>
</table>

Note: The same behavior is observed when substituting <tr> with <div> and adding display: table-row.

Holeandcorner answered 4/6, 2012 at 0:7 Comment(2)
Had a similar issue. This solved it. CSS td:hover { display:block; }Lauree
@Lauree td:hover { display:block; } changes the location of text in the table cell and slightly increases the size of the hovered table column and row.Goddamned
I
41

As previously mentioned, box-shadow property works only with elements that have display: block or display:inline-block property.

If you'll add display: block to the table cell as a general styling rule, it will collapse, since automatic width/height proportions that cells had with display:table won't be applied anymore. To simulate that behavior just assign min-width attribute to each th and td.

Then apply box-shadow to the row (on hover or without).

In summary, your code should look like this:

table { box-sizing: border-box; }
td, th { padding-left: 16px; min-width: 170px; text-align: left; }
tr { display: block; }
tr:hover { box-shadow: 0px 2px 18px 0px rgba(0,0,0,0.5); cursor: pointer; }

I've omitted vendor prefixes for simplicity.

Here is the full example:

table {
  box-sizing: border-box;
  border-bottom: 1px solid #e8e8e8;
}
td,
th {
  padding-left: 16px;
  min-width: 170px;
  border: 1px solid #e8e8e8;
  border-bottom: none;
  font: 14px/40px;
  text-align: left;
}
td {
  color: #666;
}
tr {
  display: block;
}
th {
  color: #333;
}
tr:hover {
  background-color: #fbfbfb;
  box-shadow: 0px 2px 18px 0px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
<table cellpadding="0" cellspacing="0">
  <thead>
    <tr>
      <th>Phone number</th>
      <th>Date</th>
      <th>Name</th>
      <th>Label</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0342443</td>
      <td>10 August 2013</td>
      <td>Kate</td>
      <td>Loves cats</td>
      </td>
      <tr>
        <td>0342442</td>
        <td>9 August 2013</td>
        <td>Mary</td>
        <td>Boring</td>
      </tr>
      <tr>
        <td>0342441</td>
        <td>8 August 2013</td>
        <td>Anna</td>
        <td>Loves extreme stuff</td>
      </tr>
  </tbody>
</table>

You can also check out the fiddle here.

Infatuate answered 12/7, 2013 at 7:48 Comment(2)
adding display:block. and min-width to th,td removes its ability to responsiveness of td,th according to content. this solution creates more problem than it solve.Croaker
This answer is not really correct; it's perfectly possible in modern browsers to use box-shadow with a tr element. Using transform: scale(1) in the hover style avoids the problem of other table rows being rendered "in the way" of the box shadow.Tatiana
S
50

Use transform scale(1,1) property with box-shadow it will solve the problem.

tr:hover {
  transform: scale(1);
  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  box-shadow: 0px 0px 5px rgba(0,0,0,0.3);
  -webkit-box-shadow: 0px 0px 5px rgba(0,0,0,0.3);
  -moz-box-shadow: 0px 0px 5px rgba(0,0,0,0.3);
}

Fiddle: https://jsfiddle.net/ampicx/5p91xr48/

Thanks!!

Sarasvati answered 27/12, 2017 at 12:37 Comment(3)
Please add some documentation/explanation.Wiersma
Read about The Stacking Context and how it works here: developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/…Plush
This unfortunately doesn't seem to work in Safari on macOSClactonian
I
41

As previously mentioned, box-shadow property works only with elements that have display: block or display:inline-block property.

If you'll add display: block to the table cell as a general styling rule, it will collapse, since automatic width/height proportions that cells had with display:table won't be applied anymore. To simulate that behavior just assign min-width attribute to each th and td.

Then apply box-shadow to the row (on hover or without).

In summary, your code should look like this:

table { box-sizing: border-box; }
td, th { padding-left: 16px; min-width: 170px; text-align: left; }
tr { display: block; }
tr:hover { box-shadow: 0px 2px 18px 0px rgba(0,0,0,0.5); cursor: pointer; }

I've omitted vendor prefixes for simplicity.

Here is the full example:

table {
  box-sizing: border-box;
  border-bottom: 1px solid #e8e8e8;
}
td,
th {
  padding-left: 16px;
  min-width: 170px;
  border: 1px solid #e8e8e8;
  border-bottom: none;
  font: 14px/40px;
  text-align: left;
}
td {
  color: #666;
}
tr {
  display: block;
}
th {
  color: #333;
}
tr:hover {
  background-color: #fbfbfb;
  box-shadow: 0px 2px 18px 0px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}
<table cellpadding="0" cellspacing="0">
  <thead>
    <tr>
      <th>Phone number</th>
      <th>Date</th>
      <th>Name</th>
      <th>Label</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>0342443</td>
      <td>10 August 2013</td>
      <td>Kate</td>
      <td>Loves cats</td>
      </td>
      <tr>
        <td>0342442</td>
        <td>9 August 2013</td>
        <td>Mary</td>
        <td>Boring</td>
      </tr>
      <tr>
        <td>0342441</td>
        <td>8 August 2013</td>
        <td>Anna</td>
        <td>Loves extreme stuff</td>
      </tr>
  </tbody>
</table>

You can also check out the fiddle here.

Infatuate answered 12/7, 2013 at 7:48 Comment(2)
adding display:block. and min-width to th,td removes its ability to responsiveness of td,th according to content. this solution creates more problem than it solve.Croaker
This answer is not really correct; it's perfectly possible in modern browsers to use box-shadow with a tr element. Using transform: scale(1) in the hover style avoids the problem of other table rows being rendered "in the way" of the box shadow.Tatiana
B
9

Please star this bug if you want to see it get fixed:

https://code.google.com/p/chromium/issues/detail?id=94871

If you want the table cell widths to continue to adjust themselves automatically, you can apply the shadow to the individual cells instead:

td:first-child {
  box-shadow:
    inset 0px 11px 8px -10px blue,
    inset 0px -11px 8px -10px blue,
    inset 11px 0px 8px -10px blue; 
}
td {
  box-shadow:
    inset 0px 11px 8px -10px blue,
    inset 0px -11px 8px -10px blue;
}
td:last-child {
  box-shadow:
    inset 0px 11px 8px -10px blue,
    inset 0px -11px 8px -10px blue,
    inset -11px 0px 8px -10px blue; 
}

Full example here. (jsfiddle)

(Inspired by https://mcmap.net/q/156237/-css-box-shadow-top-and-bottom-only-duplicate)

In each box shadow value:

  • Adjust the 3rd number (blur radius) to change the blur radius.
  • The 4th number (spread radius) must always be negative and its absolute value must be greater than the 3rd number (blur radius).
  • Make the 1st number (offset x) nonzero to get a shadow on the left or right. Make its absolute value 1 greater than the absolute value of the 4th number (see the example above again, much easier to see what I mean).
  • Make the 2nd number (offset y) nonzero to get a shadow at top or bottom. Make its absolute value 1 greater than the absolute value of the 4th number.
Bess answered 1/4, 2015 at 17:26 Comment(1)
Unfortunately this highlights another bug in Chrome: code.google.com/p/chromium/issues/detail?id=137481 Boooo :/Bess
P
7

I had the same issue. I was trying to highlight an entire row when the mouse was over it. Below is the css code for it:

tr:hover {
    outline: none;
    -webkit-box-shadow: inset 0 0 10px #337AB7;
    box-shadow: inset 0 0 10px #337AB7;
}

It works fine on Mozilla Firefox (38.0.1) and Internet Explorer (11.0.9600.17801), both on Windows 7. However, did not work on Chrome (43.0.2357.81).

Therefore, I had to workaround and I did a mix of the answers of Sviatoslav Zalishchuk and David Winiecki. As an result I got:

@media screen and (-webkit-min-device-pixel-ratio:0) {
    tr:hover td:first-child {
       box-shadow: inset 0px 11px 8px -10px #337AB7, 
                   inset 0px -11px 8px -10px #337AB7, 
                   inset 11px 0px 8px -10px #337AB7;
    }

    tr:hover td {
       box-shadow: inset 0px 11px 8px -10px #337AB7, 
                   inset 0px -11px 8px -10px #337AB7;
    }

    tr:hover td:last-child {
       box-shadow: inset 0px 11px 8px -10px #337AB7, 
                   inset 0px -11px 8px -10px #337AB7, 
                   inset -11px 0px 8px -10px #337AB7;
    }
}

tbody > tr:hover {
    outline: none;
    -webkit-box-shadow: inset 0 0 10px #337AB7;
    box-shadow: inset 0 0 10px #337AB7;
}

That works fine and it does not break the column width of the table and still working on Mozilla and Explorer.

Below there is a full example:

table {
  box-sizing: border-box;
  border-collapse: collapse;
}
td,
th {
  padding-left: 10px;
  padding-right: 10px;
  border: 1px solid #dddddd;
  font: 14px;
  text-align: left;
}

/*To work only on Chrome and Safari*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
  tr:hover td:first-child {
    box-shadow: inset 0px 11px 8px -10px #337AB7, 
      inset 0px -11px 8px -10px #337AB7, 
      inset 11px 0px 8px -10px #337AB7;
  }

  tr:hover td {
    box-shadow: inset 0px 11px 8px -10px #337AB7, 
      inset 0px -11px 8px -10px #337AB7;
  }

  tr:hover td:last-child {
    box-shadow: inset 0px 11px 8px -10px #337AB7, 
      inset 0px -11px 8px -10px #337AB7, 
      inset -11px 0px 8px -10px #337AB7;
  }
}

/*To work on the others browsers*/
tbody > tr:hover {
  outline: none;
  -webkit-box-shadow: inset 0 0 10px #337AB7;
  box-shadow: inset 0 0 10px #337AB7;
}
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Born</th>
      <th>City</th>      
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>David Gilmour</td>
      <td>6 March 1946</td>
      <td>Cambridge, England</td> 
	</tr>
    <tr>
      <td>Roger Waters</td>
      <td>6 September 1943</td>
      <td>Surrey, England</td>		
    </tr>
    <tr>
      <td>Nick Mason</td>
      <td>27 January 1944</td>
      <td>Birmingham, England</td>
    </tr>
    <tr>
      <td>Richard Wright</td>
      <td>28 July 1943</td>
      <td>London, England</td>
    </tr>
  </tbody>
</table>
Putrefy answered 8/6, 2015 at 13:1 Comment(1)
Thank you, works like a charm. Add tr:hover td:first-child:last-child { box-shadow: inset 0px 11px 8px -10px #337AB7, inset 11px 0px 8px -10px #337AB7, inset 0px -11px 8px -10px #337AB7, inset -11px 0px 8px -10px #337AB7; } to make it work also in single column tables.Significant
L
7

I've got an effect quite similar to box-shadow using filter and drop-shadow. It's a bit hacky and you'll need to find the best configuration of the shadow to match your scenario though.

My original class:

.project-row { 
   box-shadow: 0 0 15px 0 black;
}

My new class:

.project-row { 
   filter: drop-shadow(0 0 9px black);
}

https://codepen.io/nico_nj/pen/XWbaZPJ

Loreleilorelie answered 3/3, 2020 at 17:56 Comment(2)
I've finally "solved" my scenario using display:flex on every tr and handling the column width manually with percentages. It is way more verbose, but in my scenario I have a long list of items to apply box-shadow and using the filter approach was not an option because the performance was horrible. Here's the example with flexbox codepen.io/nico_nj/pen/eYNEoLKLoreleilorelie
This works perfectly on Safari, no need to change tr display. Thank you.Riane
S
3

Reasons behind it seem down to default CSS - the display: block was the biggest factor.

CSS / HTML / Demo

tr {
  background-color: rgb(165, 182, 229);
  display: block;
  margin-bottom: 5px;
  -moz-box-shadow: 0px 2px 2px black;
  -webkit-box-shadow: 0px 2px 2px black;
  box-shadow: 0px 2px 2px black;
}
td,th {
  padding: 5px;
  text-align: left;
}
<table>
  <tr>
    <td>&nbsp;</td>
    <th>One</th>
    <th>Two</th>
  </tr>
  <tr>
    <th>Title</th>
    <td>Three</td>
    <td>Four</td>
  </tr>
  <tr>
    <th>Title2</th>
    <td>Five</td>
    <td>Six</td>
  </tr>
  <tr>
    <th>Title3</th>
    <td>Seven</td>
    <td>Eight</td>
  </tr>
  <tr>
    <th>Title4</th>
    <td>Nine</td>
    <td>Ten</td>
  </tr>
</table>
Suction answered 4/6, 2012 at 0:30 Comment(2)
Although using display:block adds the shadow, it seems to shift everything to the left. Anything i can do to fix this?Holeandcorner
You can add th, td {min-width: 150px;}, then it will look just fine.Infatuate
F
2

Now, in v53 Chrome it fixed and box-shadow work fine for <tr></tr>!

CSS / HTML / Demo

table {
  border-spacing: 0 10px;
  border-collapse: separate;
} 
tbody {
  display: table-row-group;
  vertical-align: middle;
}
tr {
  margin-bottom: 9px;
}
tr:hover {
      box-shadow: 0 5px 8px 0 rgba(50, 50, 50, 0.35);
    -webkit-box-shadow: 0 5px 8px 0 rgba(50, 50, 50, 0.35);
    -moz-box-shadow: 0 5px 8px 0 rgba(50, 50, 50, 0.35);
}
<table class="table">
  <caption>Optional table caption.</caption>
  <thead> 
    <tr> 
      <th>#</th>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Username</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">1</th>
      <td>Mark</td>
      <td>Otto</td>
      <td>@mdo</td>
    </tr>
    <tr>
      <th scope="row">2</th>
      <td>Jacob</td>
      <td>Thornton</td>
      <td>@fat</td>
    </tr>
    <tr> 
      <th scope="row">3</th>
      <td>Larry</td>
      <td>the Bird</td>
      <td>@twitter</td>
    </tr>
  </tbody>
</table>
Feer answered 7/9, 2016 at 5:56 Comment(6)
I mean supposedly I see that the bug has been tagged as "fixed" but I still cannot see the proper rendering on my machine =(Coachman
Hm... today i will write working example and place link to it, but later time.Feer
That'd be a challenge. I really can't make it work. It works perfectly fine on ffox but not in chrome. ThanksCoachman
This is simplest example: jsfiddle.net/tafjc4vj dropbox.com/s/3tuqcfu4sl9dzht/gqs46szu3u7.JPG?dl=0Feer
Wow that's right!! Thanks a ton dude! I'd give you an extra upvote if I could. I wasn't using -webkit- prefix, silly me. You should link the fiddle on your postCoachman
still broken in 2022 on safari :(Impressionable
W
0

I wanted a box-shadow on the left side of the row when hovered:

enter image description here

I fixed it simply by setting the box-shadow on the first cell in the row. Like this:

tr:hover                { background: #EEF0F3; cursor: pointer; }
tr:hover td:first-child { box-shadow: inset 2px 0 0 0 #323335; }

I've tried it in Firefox, Chrome, and IE9. Seems to work fine.


If you want a 1px wide border around the whole row you could do something like:

tr:hover td             { box-shadow: 0 1px 0 0 black, 0 -1px 0 0 black; }
tr:hover td:first-child { box-shadow: 0 -1px 0 0 black, -1px 0 0 0 black, 0 1px 0 0 black; }
tr:hover td:last-child  { box-shadow: 0 -1px 0 0 black, 1px 0 0 0 black, 0 1px 0 0 black; }

enter image description here

Wirework answered 4/10, 2016 at 13:57 Comment(0)
C
0

You can use the pseudo element :after of the table row to display above the whole tr, with pointer events: none; and apply the box-shadow on hover of the tr.

example:

.custom-table {
    border-radius: 10px;
    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}
table {
  margin-bottom: 0;
  color: #4e4e4e;
}

thead {
  background: #000000;
  color: #FFFFFF;
  text-transform: uppercase;
  font-size: 15px;
  line-height: 18px;
  font-weight: 600;
}
th {
  padding: 20px 40px;
}
tr:hover:after {
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.3s ease-in-out;
}

tbody tr {
  background: #FFFFFF;
  position: relative;
}
tbody tr:after {
  display: block;
  content: '';
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 2;
  pointer-events: none;
  top: 0;
  left: 0;
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0);
  transition: box-shadow 0.3s ease-in-out;
}
td {
  padding: 17px 40px;
  border: 0;
  vertical-align: middle;
}
<div class="custom-table table-responsive">
    <table class="table">
        <thead class="table-header">
            <tr class="table-row">
                <th scope="col" class="table-col">Date &amp; Time</th>
                <th scope="col" class="table-col">Meeting Name</th>
                <th scope="col" class="table-col">Document</th>
                <th scope="col" class="table-col">Type of Meeting</th>
            </tr>
        </thead>
        <tbody class="table-body">
            <tr class="table-row">
                <td class="table-col"><span class="meeting-date">16 Nov 2021 <b>Saturday</b></span><span class="meeting-time">7:00 PM</span></td>
                <td class="table-col">Lorem ipsum dolor sit amet</td>
                <td class="table-col"><span class="member-document">quis nostrud exercitation ullamco</span></td>
                <td class="table-col"><span class="meeting-type type-1">MEETINGS</span></td>
            </tr>
            <tr class="table-row">
                <td class="table-col"><span class="meeting-date">16 Nov 2021 <b>Saturday</b></span><span class="meeting-time">7:00 PM</span></td>
                <td class="table-col">Lorem ipsum dolor sit amet</td>
                <td class="table-col"><span class="member-document">quis nostrud exercitation ullamco</span></td>
                <td class="table-col"><span class="meeting-type type-1">MEETINGS</span></td>
            </tr>
            <tr class="table-row">
                <td class="table-col"><span class="meeting-date">16 Nov 2021 <b>Saturday</b></span><span class="meeting-time">7:00 PM</span></td>
                <td class="table-col">Lorem ipsum dolor sit amet</td>
                <td class="table-col"><span class="member-document">quis nostrud exercitation ullamco</span></td>
                <td class="table-col"><span class="meeting-type type-1">MEETINGS</span></td>
            </tr>
        </tbody>
    </table>
</div>
Cattery answered 20/1, 2022 at 9:10 Comment(1)
This doesn't work correctly in Safari because that browser doesn't support relative positioning on table rows.Pogge
H
0

This could be done with the ::before or ::after pseudo-element

HTML - If you have a table like this

<table>
  <thead>
    <tr>
      <th>S/N</th>
      <th>Name</th>
      <th>Age</th>
      <th>Pet Choice</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Emeka Orji</td>
      <td>200</td>
      <td>Cat</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Enoch Orji</td>
      <td>12</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Favour Orji</td>
      <td>17</td>
      <td>Monkey</td>
    </tr>
  </tbody>
</table>

CSS - You can add a shadow to a table cell like this

table {
  border-collapse: collapse;
}
table td, table th {
  position: relative;
  padding: .5em;
}
tr td:first-of-type::before, tr th:first-of-type::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #6060bf;
  z-index: -1;
  
  box-shadow: 7px 1px 6px 0px #0006;
}

But the downside of this is that you may run into a few problems when trying to select and alter the value of the ::before or ::after pseudo-element with javascript. So the best solution I have to this is:

You could put a span element inside the table cell you want to style like this:

HTML

<table>
  <thead>
    <tr>
      <th>S/N <span class="shadow"></span></th>
      <th>Name</th>
      <th>Age</th>
      <th>Pet Choice</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1 <span class="shadow"></span></td>
      <td>Emeka Orji</td>
      <td>200</td>
      <td>Cat</td>
    </tr>
    <tr>
      <td>2 <span class="shadow"></span></td>
      <td>Enoch Orji</td>
      <td>12</td>
      <td>Dog</td>
    </tr>
    <tr>
      <td>3 <span class="shadow"></span></td>
      <td>Favour Orji</td>
      <td>17</td>
      <td>Monkey</td>
    </tr>
  </tbody>
</table>

And in your CSS style the shadow element with the same styles you as before, like so:

table {
  border-collapse: collapse;
}
table td, table th {
  position: relative;
  padding: .5em;
}
.shadow {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #6060bf;
  z-index: -1;
  
  box-shadow: 7px 1px 6px 0px #0006;
}

This way you would be able to select the span element in your javascript like this:

const cellShadow = document.querySelector('td .shadow');

Check out this pen below. Full code demo there.

https://codepen.io/emekaorji/pen/QWQzBeM

Hewart answered 13/6, 2022 at 18:12 Comment(0)
M
-1

in react, i have combined the answer as below. It worked fine in chrome, >firefox, ie11

.select_row{
    color: #43B149;
    font-weight: bolder !important;
    background: #e4e5e6 !important;
    box-shadow: 1px 0px 1px 0px #cad6ce !important;
    -moz-box-shadow:1px 0px 1px 0px #cad6ce !important;
    -webkit-box-shadow:1px 0px 1px 0px #cad6ce !important;
    transform: scale(1);
    -webkit-transform: scale(1);
    -moz-transform: scale(1);
    -ms-transform: scale(1);
    td{box-shadow: 0px 3px 0px 0px #cad6ce !important;
        -moz-box-shadow:0px 3px 0px 0px #cad6ce !important;
        -webkit-box-shadow:0px 3px 0px 0px #cad6ce !important;
        background: #e4e5e6 !important;
    }
}
.table-forecast{
    border-collapse: separate;
    border-spacing: 0px;
}
Machiavellian answered 22/11, 2018 at 8:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.