<div class="p-4">
  <div class="mb-4">
    <p>this pen uses <a target="__blank" href="https://github.com/aholachek/animate-css-grid">animate-css-grid</a>
    </p>
    <p>
      If you use React, you might want to try out <a href="https://github.com/aholachek/react-flip-toolkit" target="__blank">react-flip-toolkit</a>
    </p>
    <button class="btn js-toggle-grid-gap">toggle <code>grid-gap</code></button>
    <button class="btn js-toggle-grid-columns">toggle <code>grid-template-columns</code></button>

    <p>click a card to toggle the <code>grid-column</code> and <code>grid-row </code>properties on the card</p>
  </div>

  <div class="grid grid--full mb-4">
  </div>
  <button class="btn js-add-card">add a card</button>
</div>
/* layout */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  grid-auto-rows: 12rem;
  grid-gap: 16px;
  grid-auto-flow: dense;
}

.grid--big-columns {
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.grid--big-gap {
  grid-gap: 2.5rem;
}

/* styling */

.card--expanded {
  grid-column: span 3;
  grid-row: span 3;
  .card__img {
    transform: scale(1.03);
  }
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

.fade-in {
  opacity: 0;
  animation: fadeIn 0.4s forwards;
  animation-delay: 0.3s;
}

.card {
  cursor: pointer;
  overflow: hidden;
  position: relative;
}

.card__img {
  transition: transform 1s;
}

body {
  background-color: #191919;
  color: lightgray;
  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI",
    "Roboto", "Helvetica Neue", Arial, sans-serif;
  font-size: 1.1rem;
}

.mb-4 {
  margin-bottom: 1rem;
}

.p-4 {
  padding: 1rem;
}

button {
  padding: 0.75rem;
  margin-right: 0.75rem;
  background-color: #191919;
  color: lightgray;
  border: 1px solid lightgray;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: hsla(0, 0%, 83%, 0.05);
}
button:focus {
  box-shadow: 0 0 0 3px #7396e4;
  outline: none;
}

a {
  font-weight: bold;
  color: #7396e4;
  text-decoration: none;
  &:hover {
    text-decoration: underline;
  }
}

code {
  color: #7396e4;
}
View Compiled
window.CP.PenTimer.MAX_TIME_IN_LOOP_WO_EXIT = 6000;
const grid = document.querySelector(".grid");

// event handler to toggle grid sizing
document
  .querySelector(".js-toggle-grid-columns")
  .addEventListener("click", () => grid.classList.toggle("grid--big-columns"));

document
  .querySelector(".js-toggle-grid-gap")
  .addEventListener("click", () => grid.classList.toggle("grid--big-gap"));

const addCard = () => {
  return fetch(
    `https://source.unsplash.com/random/${Math.floor(Math.random() * 1000)}`
  ).then(
    response => {
      grid.insertAdjacentHTML(
        "beforeend",
        `  <div class="card">
          <div>
            <img src=${response.url} class="card__img"/>
          </div>
        </div>
    `
      );
    },
    () => {}
  );
};

// event handler to add a new card
document.querySelector(".js-add-card").addEventListener("click", addCard);

// event handler to toggle card size on click
grid.addEventListener("click", ev => {
  let target = ev.target;
  while (target.tagName !== "HTML") {
    if (target.classList.contains("card")) {
      target.classList.toggle("card--expanded");
      return;
    }
    target = target.parentElement;
  }
});

Promise.all([...Array(10).keys()].map(addCard)).then(() => {
  animateCSSGrid.wrapGrid(grid, {
    duration: 350,
    stagger: 10,
    onStart: elements =>
      console.log(`started animation for ${elements.length} elements`),
    onEnd: elements =>
      console.log(`finished animation for ${elements.length} elements`)
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/[email protected]/dist/main.js