Shadow effect is present under every cell in the table row

I am struggling to create an HTML table with proper vertical spacing between rows and a shadow effect beneath each row.

Unfortunately, the shadow always ends up overlapping other table content.

I have tried adjusting the positioning of elements and setting z-index values without success.

https://i.sstatic.net/T3dlL.png

  table {
    border-collapse: separate;
    border-spacing: 0;
  }
  td,
  th {
    min-width: 170px;
  }

  .shadow {
    position: relative;
    z-index: 1;
    margin: 2px 0 2px 0;
  }

  <span class="unique">.shadow:before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: -1;
    box-shadow: 0 0 10px 10px #000;</span>
<main>
  <table>
    <thead>
      <tr>
        <td>head</td>
        <td>head</td>
        <td>head</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
      </tr>
      <tr>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
      </tr>
      <tr>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
        <td><div class="shadow">div</div></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>foot</td>
        <td>foot</td>
        <td>foot</td>
      </tr>
    </tfoot>
  </table>
</main>

Answer №1

You can achieve this by following these steps.

table {
    border-collapse: collapse;
    border-spacing: 0;
  }
  
  .shadow {
    position: relative;
    z-index: 1;
    margin: 2px 0 2px 0;
  }

  .shadow:before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: -1;
    box-shadow: 0 0 2px 2px #000; 
    }
    
  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);
       cursor: pointer;
       box-shadow: 0px 2px 18px 0px rgba(0, 0, 0, 0.5);
       background-color: #fbfbfb;
}


td, th {
 text-align:center;
  min-width: 170px;
  border: 1px solid #999;
  padding: 0.5rem;
}
<main>
  <table>
    <thead>
      <tr>
        <td>heading</td>
        <td>heading</td>
        <td>heading</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><div class="shadow">1</div></td>
        <td><div class="shadow">2</div></td>
        <td><div class="shadow">3</div></td>
      </tr>
      <tr>
        <td><div class="shadow">4</div></td>
        <td><div class="shadow">5</div></td>
        <td><div class="shadow">6</div></td>
      </tr>
      <tr>
        <td><div class="shadow">7</div></td>
        <td><div class="shadow">8</div></td>
        <td><div class="shadow">9</div></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>footer</td>
        <td>footer</td>
        <td>footer</td>
      </tr>
    </tfoot>
  </table>
</main>

Answer №2

table {
    border-collapse: collapse;
    border-spacing: 0;
  }
  
  .shadow {
    position: relative;
    z-index: 1;
    margin: 2px 0 2px 0;
  }

  .shadow:before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: -1;
    box-shadow: 0 0 0px 0px #000; 
    }
    

  
  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);
}


td, th {
 text-align:center;
  min-width: 170px;
  border: 1px solid #999;
  padding: 0.5rem;
}
<main>
  <table>
    <thead>
      <tr>
        <td>head</td>
        <td>head</td>
        <td>head</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><div class="shadow">1</div></td>
        <td><div class="shadow">2</div></td>
        <td><div class="shadow">3</div></td>
      </tr>
      <tr>
        <td><div class="shadow">4</div></td>
        <td><div class="shadow">5</div></td>
        <td><div class="shadow">6</div></td>
      </tr>
      <tr>
        <td><div class="shadow">7</div></td>
        <td><div class="shadow">8</div></td>
        <td><div class="shadow">9</div></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>foot</td>
        <td>foot</td>
        <td>foot</td>
      </tr>
    </tfoot>
  </table>
</main>

Answer №3

Here is one method with detailed comments within the code:

/* Resetting default padding and margins, adjusting element sizes to include padding and borders */
*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

table {
  /* Custom properties for consistent styling */
  --tr-space-between: 0.5rem;
  --td-padding-block: calc(var(--tr-space-between)/2);
  --shadow-color: lightgray;
  --row-color: #fff;
  --row-radius: 0.5rem;
  background-color: transparent;
  border-collapse: collapse;
  border-spacing: 0;
  filter: drop-shadow(0 0 0.5rem var(--shadow-color));
  margin-inline: auto;
}

td,
th {
  min-width: 170px;
  background-color: transparent;
  padding-block: var(--td-padding-block);
}

td:first-child .content {
  border-start-start-radius: var(--row-radius);
  border-end-start-radius: var(--row-radius);
}

td:last-child .content {
  border-start-end-radius: var(--row-radius);
  border-end-end-radius: var(--row-radius);
}

.content {
  background-color: var(--row-color);
  padding: 0.5rem;
}
<main>
  <table>
    <thead>
      <tr>
        <th>head</th>
        <th>head</th>
        <th>head</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <div class="content">div</div>
        </td>
        <td>
          <div class="content">div</div>
        </td>
        <td>
          <div class="content">div</div>
        </td>
      </tr>
    <tfoot>
      <tr>
        <td>foot</td>
        <td>foot</td>
        <td>foot</td>
      </tr>
    </tfoot>
  </table>
</main>

This example showcases another technique as well:

const changeBackground = (evt) => {
  let {
    currentTarget
  } = evt, {
    value
  } = currentTarget,
  table = document.querySelector('table');

  table.dataset.shadow = value;
}

document.querySelectorAll('input[type=radio]').forEach(
  (el) => el.addEventListener('change', changeBackground)
);

document.querySelector('input:checked').dispatchEvent(new Event('change'));
/* More CSS adjustments for various effects */

body {
  background-image:
    repeating-linear-gradient(
      to bottom left,
      transparent,
      hsl(140deg 90% 80% / 0.7)
    ), radial-gradient(
      at 0 0,
      hsl(300deg 95% 85% / 1),
      hsl(180deg 95% 85% / 1)
    );
  block-size: 100vh;
  padding: 1rem;
}

form {
  inline-size: 70%;
  margin-block: 1rem;
  margin-inline: auto;
}

fieldset {
  border: 0 none transparent;
  display: flex;
  flex-flow: row wrap;
  gap: 1rem;
  justify-content: space-between;
  padding: 1rem;
}

label {
  flex-grow: 1;
}

.inputText {
  --active-indication: hsl(0deg 75% 70% / 0.55);
  background-color: #cccd;
  background-image:
    linear-gradient(
    270deg,
    var(--active-indication) 0 1.5rem,
    #0009 1.5rem calc(1.5rem + 1px),
    transparent calc(1.5rem + 1px)
  );
  border: 1px solid #0009;
  border-radius: 1rem;
  display: block;
  padding: 0.75rem;
  padding-inline-end: 2rem;

}

input[type=radio] {
  position: absolute;
  left: -2000px;
}

input:checked + .inputText {
  --active-indication: hsl(160deg 95% 75% / 1);
}

table {
  --tr-space-between: 0.5rem;
  --td-padding-block: calc(var(--tr-space-between)/2);
  --shadow-color: #339a;
  --row-color: #fff;
  --row-inset: 1rem;
  --row-radius: 0.5rem;
  background-color: transparent;
  border-collapse: collapse;
  border-spacing: 0;
  margin-block: 1rem;
  margin-inline: auto;
}

table[data-shadow="drop-shadow"] {
  filter: drop-shadow(0 0 2rem var(--shadow-color));
}

table[data-shadow="box-shadow"] {
  box-shadow: 0.5rem 0.5rem 2rem var(--shadow-color);
}

table[data-shadow="backdrop-filter"] {
  backdrop-filter: hue-rotate(245deg) opacity(0.4);
}

td,
th {
  min-width: 170px;
  background-color: transparent;
  padding-block: var(--td-padding-block);
}

td:first-child .content {
  border-start-start-radius: var(--row-radius);
  border-end-start-radius: var(--row-radius);
}

td:last-child .content {
  border-start-end-radius: var(--row-radius);
  border-end-end-radius: var(--row-radius);
}

td:first-child {
  padding-inline-start: var(--row-inset);
}

td:last-child {
  padding-inline-end: var(--row-inset);
}

.content {
  background-color: var(--row-color);
  padding: 0.5rem;
}
<main>
  <form action="#" id="choices" method="post">
    <fieldset>
      <legend>Choose approach</legend>
      <label>
        <input type="radio" name="shadowType" value="drop-shadow" checked>
        <span class="inputText"><code>filter: drop-shadow()</code></span>
      </label>
      <label>
        <input type="radio" name="shadowType" value="box-shadow" >
        <span class="inputText"><code>box-shadow</code></span>
      </label>
      <label>
        <input type="radio" name="shadowType" value="backdrop-filter" >
        <span class="inputText"><code>backdrop-filter</code></span>
      </label>
    </fieldset>
  </form>
  <table>
    <thead>
      <tr>
        <th>head</th>
        <th>head</th>
        <th>head</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          <div class="content">div</div>
        </td>
        <td>
          <div class="content">div</div>
        </td>
        <td>
          <div class="content">div</div>
        </td>
      </tr>
    <tfoot>
      <tr>
        <td>foot</td>
        <td>foot</td>
        <td>foot</td>
      </tr>
    </tfoot>
  </table>
</main>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Blocking users on a PHP social networking platform

I'm in the process of developing a social networking platform and I am currently working on adding a feature that allows users to block other users. However, I am facing challenges when it comes to implementing this feature. In my database, there is ...

The reason behind the clickable issue with my duplicate <ion-select>

I've been working on a form using HTML, CSS, and JavaScript where I implemented an "Add" button to duplicate the form. The issue arises with the ion-select element within the duplicated form. While the original form displays all predefined options upo ...

How to retrieve the same value from multiple selections using Vanilla JavaScript and multiple select options?

Why do we consistently receive the same value and index when using the ctl key to select multiple options? document.querySelector('select').addEventListener('change', function(e) { console.log(this.selectedIndex) console.log(e.ta ...

Tips for speeding up your website by preloading versioned files in HTML

Tools like Google Lighthouse and PageSpeed recommend preloading important requests using <link rel=preload> to enhance website performance. When it comes to static files with unchanging filenames, the process is straightforward. However, how can I ...

Can someone please explain how I can implement a multi-submenu feature using JavaScript?

HTML CODES: <header> <nav> <ul> <li class="asmenu"><a href="#">Menu1 <i class="fa fa-caret-down"></i></a> <ul class="submenu deact ...

Cross-browser compatibility problem: Firefox not displaying layout properly

I am encountering browser problems, as well as issues when using the same browser on a different computer. The links on my website are not positioned correctly over the background. When viewing with Firefox, the opacity and positioning features are not fu ...

Achieving nested classes in CSS: a comprehensive guide

I am encountering an issue with my CSS while trying to create a dropdown on hover. The problem seems to be related to nested classes inside a div structure. It appears that the dropdown list is not displaying properly, leading me to believe there might be ...

"Exploring the Dynamic Display of Ajax with HTML5 Canvas

This is my first time exploring the world of ajax, and I'm finding it quite challenging to grasp the concept and functionality. What I aim to achieve: I envision a scenario where I can freely draw on a canvas and simply hit save. Upon saving, the da ...

Creating a dynamic webpage with flexible design and interconnected containers using the Bootstrap framework

Creating a responsive layout with nested divs using Bootstrap Check out my HTML code below: <div class="container-fluid" style="height: 350px;"> <div class="row-fluid clearfix" style="height: 100%"> <div class="col-md-9 column" ...

Having trouble rendering an HTML webpage using Flask's RESTful API? Your webpage might be displaying improperly

Trying to display an HTML page on local host using a restful flask API. The content of the HTML page appears as a string with "" instead of rendering the actual page. class data(Resource): def get(self): #return "Welcome!" return rende ...

Selenium is unable to interact with iframes

I'm attempting to extract the Job Description and Job Requirements from this specific link using selenium. Check out my code below: driver = webdriver.Firefox() url = "https://www.jobsbank.gov.sg/ICMSPortal/portlets/JobBankHandler/SearchDetail.do?id= ...

Is there a way to modify the variable in order to switch the font of the heading every second using CSS and JavaScript?

I'm trying to create a heading that changes fonts every second, but I'm having trouble changing the variable to set it to another font. Check out my code here. Despite watching tutorials, everything seemed too confusing. var root = document.q ...

Moving elements upwards and downwards using CSS transitions

I am currently designing a metro tiles menu for my website, without using JavaScript and only relying on HTML and CSS. The issue I am facing involves the sliding tiles and the direction in which they slide. Additionally, there seems to be a problem where ...

Sending chosen choice to controller method

I'm working with a table that contains inputs and angular models. <td> <select class="form-control" id=""> <option ng-model="mfrNo" ng-repe ...

Hovering into Transition Time

My article card has a transition on the top attribute of the info div, which is supposed to be smooth and last for 0.3 seconds. However, the description suddenly appears during this transition. I'm trying to figure out why this is happening and how to ...

Guide on navigating to a specific section on a different page using scrolling

Adding a link for a "read more" button is simple. Just include the href attribute like this: <a href="about.html#post2">readmore</a> In my index.html page, I have implemented Bootstrap 3 with scroll animations for navbar sections. When clicki ...

Checkbox offering a tri-state option

Seeking help on creating a checkbox with three states. I have implemented a method to toggle between these states upon clicking. However, the issue is that this method is only triggered after the HTML changes. As a result, the checkbox's navigation be ...

What are the best ways to format an outgoing email using inline CSS?

On my upcoming website, I have set up a single form for guests to subscribe. The issue I am facing is with styling the email that is sent upon submission. I attempted using inline CSS, but it doesn't seem to be working. Instead of transforming the cod ...

Align the center of a grid div that does not contain any items

Below are the code snippets provided: .grades_dashboard_m {} .three_separation { width: 100%; display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 60px; } .grades_dashboard_box { height: 130px; width: 160px; background-color: #00 ...

Transforming the add to cart button into a view button within the product listings: an easy guide

I am currently developing a unique ecommerce website called bookslab.in. To enhance the user experience, I would like to replace the "add to cart" button with a "view details" button when users view the list of available products. Furthermore, when users c ...