How to make image cards flip on hover, using auto layout list section - Squarespace 7.1
In order to create this you’ll need to have an even number of items in your auto layout. Essentially what the code does is it takes the second item, and it’ll reveal it on hover to the user.
It works best with images changing so you can have some fun ‘meet the team’ page or something else like that were you are revealing something hidden.
Part 1
Add this to Custom CSS and replace “xxxxxxx” with the specific Section ID
/** Auto Layout 3D card flip **/
[data-section-id="xxxxx"] {
.list-item {
.flip-container {
width: 100%;
margin-bottom: 4%;
}
.flip-inner {
// base state
transform: rotateY(0deg);
}
.flip-front,
.flip-back {
.list-item-media-inner {
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
}
.flip-inner .list-item-media {
margin-bottom: 0 !important;
}
}
/* DESKTOP: real hover */
@media (hover: hover) and (pointer: fine) {
.list-item:hover .flip-inner {
transform: rotateY(180deg);
}
}
/* TOUCH: flip via .is-flipped class */
@media (hover: none) and (pointer: coarse) {
.list-item.is-flipped .flip-inner {
transform: rotateY(180deg);
}
}
}
Part 2
Add to Code Injection and replace “xxxxxxx” with the same specific Section ID.
<!-- 3D Image flip on hover -->
<script>
(function() {
const section = document.querySelector('[data-section-id="xxxxxxxxx"]');
if (!section) return;
const items = section.querySelectorAll('.list-item');
items.forEach((item, index) => {
// Every even item (index 1, 3, 5...) becomes the flip target
if (index % 2 === 1) {
const hoverImage = item.querySelector('.list-item-media');
const targetItem = items[index - 1];
if (hoverImage && targetItem) {
const primaryMedia = targetItem.querySelector('.list-item-media');
if (primaryMedia) {
// Create flip container
const flipContainer = document.createElement('div');
flipContainer.classList.add('flip-container');
flipContainer.style.cssText = `
perspective: 2000px;
position: relative;
`;
// Create inner flip wrapper
const flipInner = document.createElement('div');
flipInner.classList.add('flip-inner');
flipInner.style.cssText = `
position: relative;
width: 100%;
transition: transform 0.35s ease; /* faster */
transform-style: preserve-3d;
will-change: transform;
`;
// Clone hover image as back
const backImage = hoverImage.cloneNode(true);
backImage.classList.add('flip-back');
backImage.style.cssText = `
position: absolute;
top: 0;
left: 0;
width: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
transform: rotateY(180deg);
`;
// Style primary image as front
primaryMedia.classList.add('flip-front');
primaryMedia.style.cssText = `
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
`;
// Assemble structure
const mediaParent = primaryMedia.parentElement;
mediaParent.insertBefore(flipContainer, primaryMedia);
flipContainer.appendChild(flipInner);
flipInner.appendChild(primaryMedia);
flipInner.appendChild(backImage);
// Mark list item as having flip
targetItem.classList.add('has-flip');
// TAP / CLICK TOGGLE (better on mobile)
flipContainer.addEventListener('click', function(e) {
// Avoid bubbling causing weird behavior
e.stopPropagation();
targetItem.classList.toggle('is-flipped');
}, { passive: true });
}
// Hide original even item
item.style.display = 'none';
}
}
});
})();
</script>