bike-bear-logobike-bear-logobike-bear-logobike-bear-logo
✕
Published by bikebear on June 30, 2026
Categories
  • GSAP
  • Layout
  • DateJune 30, 2026

HTML

<div class="bento-container cols-1-3-1 rows-1-3-1">
  <div data-column="0" data-row="0" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-1.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="1" data-row="0" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-2.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="2" data-row="0" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-3.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="0" data-row="1" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-6.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="1" data-row="1" class="bento-item center-piece">
    <img src="https://assets.codepen.io/16327/portrait-image-4.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="2" data-row="1" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-8.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="0" data-row="2" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-image-14.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="1" data-row="2" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-pattern-3.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
  <div data-column="2" data-row="2" class="bento-item">
    <img src="https://assets.codepen.io/16327/portrait-pattern-1.jpg" alt="">
    <div class="image-overlay"></div>
  </div>
</div>

CSS

:root {
  --bg-color: #f0f2f5;
  --gap: 15px;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
}

/* The Bento Grid Logic */
.bento-container {
  display: grid;
  gap: var(--gap);
  width: 90vw;
  height: 90vh;
  max-width: 1000px;
  max-height: 800px;
}

/*
Specific classes for each event target
*/
.bento-container.rows-3-1-1 {
  grid-template-rows: 3fr 1fr 1fr;
}

.bento-container.rows-1-3-1 {
  grid-template-rows: 1fr 3fr 1fr;
}

.bento-container.rows-1-1-3 {
  grid-template-rows: 1fr 1fr 3fr;
}

.bento-container.cols-3-1-1 {
  grid-template-columns: 3fr 1fr 1fr;
}

.bento-container.cols-1-3-1 {
  grid-template-columns: 1fr 3fr 1fr;
}

.bento-container.cols-1-1-3 {
  grid-template-columns: 1fr 1fr 3fr;
}

.bento-item {
  background-color: var(--card-color);
  border-radius: 12px;
  box-shadow: 0 4px 6px rgba(255, 252, 225, 0.25);
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  color: #333;
  position: relative;
  cursor: pointer;
  overflow: hidden;
  border: 1px solid rgba(255, 252, 225, 0.5);

  img {
    position: absolute;
    inset: 0;
    object-fit: cover;
    width: 100%;
    height: 100%;
    z-index: 1;
  }

  .image-overlay {
    position: absolute;
    inset: 0;
    background-color: #333;
    opacity: 0;
    z-index: 2;
  }
}

/* Hover Effect: Scale up and bring to front */
.bento-item:hover {
  z-index: 10;
}

JS

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
   <script src="https://unpkg.com/gsap@3/dist/Flip.min.js"></script>
<script>
jQuery(document).ready(function($) {
console.clear();

gsap.registerPlugin(Flip);

const bentoContainer = document.querySelector(".bento-container");
const bentoItems = bentoContainer.querySelectorAll("[data-row]");
const rowClasses = ["rows-3-1-1", "rows-1-3-1", "rows-1-1-3"];
const colClasses = ["cols-3-1-1", "cols-1-3-1", "cols-1-1-3"];
// Remember 0 index for the classes array, same for the data attribute on the HTML elements
let activeColumn = 1,
  activeRow = 1,
  doFlip = false;

bentoItems.forEach((e, i) => {
  const colNumber = e.dataset.column;
  const rowNumber = e.dataset.row;
  e.addEventListener("mouseenter", () => {
    // console.log("Item", i, "column", colNumber, "row", rowNumber);
    const state = Flip.getState(bentoItems);
    if (colNumber !== activeColumn) {
      bentoContainer.classList.remove(colClasses[activeColumn]);
      bentoContainer.classList.add(colClasses[colNumber]);
      activeColumn = colNumber;
      doFlip = true;
    }
    if (rowNumber !== activeRow) {
      bentoContainer.classList.remove(rowClasses[activeRow]);
      bentoContainer.classList.add(rowClasses[rowNumber]);
      activeRow = rowNumber;
      doFlip = true;
    }
    doFlip &&
      Flip.from(state, {
        duration: 0.4,
        ease: "power2.out",
        onStart: () => (doFlip = false),
        absolute: true
      });
  });
});

bentoContainer.addEventListener("mouseleave", () => {
  // Toggle the boolean just in case
  doFlip = true;
  // Get the state
  const state = Flip.getState(bentoItems);

  // Update the classes in the container
  bentoContainer.classList.remove(colClasses[activeColumn]);
  bentoContainer.classList.remove(rowClasses[activeRow]);
  bentoContainer.classList.add(colClasses[1]);
  bentoContainer.classList.add(rowClasses[1]);

  // Update the index values
  activeColumn = 1;
  activeRow = 1;

  // Run the Flip Animation
  Flip.from(state, {
    duration: 0.4,
    ease: "power2.out",
    onStart: () => (doFlip = false),
    absolute: true
  });
});



});
	</script>

Related posts

June 30, 2026

Inertia trail burst


Read more
June 30, 2026

Matter JS


Read more
March 31, 2026

Text Marquee GSAP


Read more
© 2026 Betheme by Muffin group | All Rights Reserved | Powered by WordPress