Search code examples
htmlcsscss-gridbox-shadow

Box shadow around column of CSS grid


I currently have a CSS grid with a dynamic number of rows where there are subsets of the rows that should be grouped together. I'd like to wrap the first column of those groups together with a drop shadow, but I can't figure out how to do this. I'm able to accomplish what I want with a border, because I'm able to drop the top and bottom border of the middle elements.

Is there a way to do this with or without a grid layout?

.grid {
  display: grid;
  grid-template-columns: 250px 250px 250px;
  grid-column-gap: 20px;
}

.top,
.middle,
.bottom {
  border: 2px solid black;
}

.top {
  border-bottom: none;
}

.middle {
  border-top: none;
  border-bottom: none;
}

.bottom {
  border-top: none;
}

.title {
  text-align: center;
  
  padding: 5px 20px;
}

.title span {
  margin: 0 20px;
}

.title,
.details,
.actions {
  text-align: center;
  vertical-align: middle;
  margin: auto 0;
}
<div class="grid">
  <span class="top title">
    <span>row 1 title</span>
  </span>
  <span class="details">row 1 details</span>
  <span class="actions">row 1 actions</span>
    
  <span class="middle title">
    <span>row 2 title</span>
  </span>
  <span class="details">row 2 details</span>
  <span class="actions">row 2 actions</span>
    
  <span class="middle title">
    <span>row 3 has an extra long tile that wraps around</span>
  </span>
  <div class="details">row 3 details</div>
  <span class="actions">row 3 actions</span>
    
  <span class="bottom title">
    <span>row 4 title</span>
  </span>
  <span class="details">row 4 details</span>
  <span class="actions">row 4 actions</span>
  
  <span class="top title">
    <span>row 5 title</span>
  </span>
  <span class="details">row 5 details</span>
  <span class="actions">row 5 actions</span>
  
  <span class="bottom title">
    <span>row 6 title</span>
  </span>
  <span class="details">row 6 details</span>
  <span class="actions">row 6 actions</span>
</div>


Solution

  • There is no way to apply styles to all grid items in a specific column or row or group them for that matter. You are already doing the possible option to target the elements directly.


    Hacky solution

    Here I'm going to use the fact that you are using top, middle and bottom clases and creating and effect of box shadow:

    • use a convenient box-shadow to a pseudo element placed behind the grid items in the first column,

    • use background on the grid item to match the column and therefore hiding from view the shadow in between rows,

    • now use a margin to separate at the bottom class.

    .grid {
      display: grid;
      grid-template-columns: 250px 250px 250px;
      grid-column-gap: 20px;
    }
    
    .top:after,
    .middle:after,
    .bottom:after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: -1;
      box-shadow: 0 0px 10px 2px #ddd;
      background: #fff;
    }
    
    .title.bottom {
      margin-bottom: 15px;
      background: transparent;
    }
    
    .title {
      text-align: center;
      position: relative;
      padding: 5px 20px;
      background: #fff;
    }
    
    .title span {
      margin: 0 20px;
    }
    
    .title,
    .details,
    .actions {
      text-align: center;
      vertical-align: middle;
      margin: auto 0;
    }
    <div class="grid">
      <span class="top title">
        <span>row 1 title</span>
      </span>
      <span class="details">row 1 details</span>
      <span class="actions">row 1 actions</span>
        
      <span class="middle title">
        <span>row 2 title</span>
      </span>
      <span class="details">row 2 details</span>
      <span class="actions">row 2 actions</span>
        
      <span class="middle title">
        <span>row 3 has an extra long tile that wraps around</span>
      </span>
      <div class="details">row 3 details</div>
      <span class="actions">row 3 actions</span>
        
      <span class="bottom title">
        <span>row 4 title</span>
      </span>
      <span class="details">row 4 details</span>
      <span class="actions">row 4 actions</span>
      
      <span class="top title">
        <span>row 5 title</span>
      </span>
      <span class="details">row 5 details</span>
      <span class="actions">row 5 actions</span>
      
      <span class="bottom title">
        <span>row 6 title</span>
      </span>
      <span class="details">row 6 details</span>
      <span class="actions">row 6 actions</span>
    </div>