Items in grid don't resize in response to animation

Viewed 37

I have a grid of four squares and I want the other squares to shrink responsively when one expands on hover. They do respond, but only after the transition is complete for the expanding square. Why do they wait until the animation is complete to resize? Is it possible to do this so they respond in real-time to the expanding square?

main {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    width: 200px;
    height: 200px;
    gap: 10px;
    transition: all 1s linear;
}

.square {
    background-color: rebeccapurple;
    width: 100%;
    height: 100%;
    transition: all 1s linear;
}

.square:hover {
    width: 150px;
    height: 150px;
    transition: all 1s linear;
}

body {
    display: flex;
    justify-content: center;
}
    <body>
      <main>
        <div class="square" id="one"></div>
        <div class="square" id="two"></div>
        <div class="square" id="three"></div>
        <div class="square" id="four"></div>
      </main>
    </body>
    

2 Answers

I just did something similar (related article for full detail: https://css-tricks.com/zooming-images-in-a-grid-layout/)

.gallery {
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1;     /* control the scale factor */
  
  display: grid;
  gap: var(--g);
  width: calc(2*var(--s) + var(--g));
  aspect-ratio: 1;
  grid-template-columns: repeat(2,auto);
}

.gallery > img {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  object-fit: cover;
  cursor: pointer;
  transition: .35s linear;
}

.gallery img:hover{
  width:  calc(var(--s)*var(--f));
  height: calc(var(--s)*var(--f));
}


body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-content: center;
  background: #60c4ff;
}
<div class="gallery">
  <img src="https://picsum.photos/id/1028/300/300" alt="a forest after an apocalypse">
  <img src="https://picsum.photos/id/15/300/300" alt="a waterfall and many rocks">
  <img src="https://picsum.photos/id/1040/300/300" alt="a house on a mountain">
  <img src="https://picsum.photos/id/106/300/300" alt="sime pink flowers">
</div>

It works with divs as well:

.gallery {
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1;     /* control the scale factor */
  
  display: grid;
  gap: var(--g);
  width: calc(2*var(--s) + var(--g));
  aspect-ratio: 1;
  grid-template-columns: repeat(2,auto);
}

.gallery > div {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  cursor: pointer;
  background: purple;
  transition: .35s linear;
}

.gallery div:hover{
  width:  calc(var(--s)*var(--f));
  height: calc(var(--s)*var(--f));
}


body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-content: center;
  background: #60c4ff;
}
<div class="gallery">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Instead of changing the height and width on :hover try using padding instead. Also, the transition should be on the non-hovered state of the element that is being animated only.

main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  width: 200px;
  height: 200px;
  gap: 10px;
}

.square {
  background-color: rebeccapurple;
  transition: all 1s linear;
}

.square:hover {
  padding: 75px;
}

body {
  display: flex;
  justify-content: center;
}
<body>
  <main>
    <div class="square" id="one"></div>
    <div class="square" id="two"></div>
    <div class="square" id="three"></div>
    <div class="square" id="four"></div>
  </main>
</body>

Related