davallree
davallree

Reputation: 13

Change CSS grid-area size based on child size change

trying to create a "fluid grid" interaction using hover states.

Goal: When hovering over a card that is within a grid, the card increases in size and "pushes" the other cards in other columns and rows making them smaller.

Problem: I thought using the "auto" size for the grid parent would work, but it's not. Code below

.shape-card-container {
  width: 100vw;
  height: 100vh;
  display: grid;
  grid-template-columns: repeat(2, auto);
  grid-template-rows: repeat(2, auto);
  grid-column-gap: 4px;
  grid-row-gap: 4px;
}

.shape-card {
  width: 100%;
  height: 100%;
  background: blue;
  border-radius: 64px;
  cursor: pointer;
  overflow: hidden;
  transition: background 300ms cubic-bezier(0.66, 0.11, 0.03, 0.96);
}

.shape-card:hover {
  width: 105%;
  height: 105%;
}
<div class="shape-card-container">
  <div class="shape-card">
   
  </div>
  <div class="shape-card">
    
  </div>
  <div class="shape-card">
   
  </div>
  <div class="shape-card">
   
  </div>
</div>

Upvotes: 0

Views: 1573

Answers (1)

connexo
connexo

Reputation: 56803

The problem is your percentage-based approach, which can never work, because it is fundamentally flawed by concept.

When used in width or height, percentages relate to the containing context, which in this case, is the grid cell.

Resizing the content of a grid cell 105% will always make your element exceed the grid cell it's placed in.

If the grid cell would resize accordingly to accomodate for the increase in size, how would the element be 105%? It only is 105% if the containing context does not resize accordingly, otherwise in that resized scenario it would be 100% of the resized cell again (which would violate the rules defined for :hover).

When you use pixel-based values along with min-content instead of auto, the grid does what you expect:

.grid {
  width: 100vw;
  height: 100vh;
  display: grid;
  grid-template-columns: repeat(2, min-content);
  grid-template-rows: repeat(2, min-content);
  grid-column-gap: 4px;
  grid-row-gap: 4px;
}

.cell {
  width: 200px;
  height: 100px;
  background: blue;
  border-radius: 64px;
  cursor: pointer;
  overflow: hidden;
  transition: all 300ms cubic-bezier(0.66, 0.11, 0.03, 0.96);
}

.cell:hover {
  background-color: teal;
  width: 250px;
  height: 150px;
}
<div class="grid">
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
  <div class="cell"></div>
</div>

Upvotes: 2

Related Questions