Clickable Thumbnails on List Section Carousels
By default, Squarespace doesn't allow images within List Sections to be clickable. While making images clickable is straightforward for the Simple List layout, Carousel and Banner layouts are a bit more challenging. Specifically, these layouts struggle because browsers have difficulty distinguishing between a simple click and a click-and-drag gesture.
The JavaScript and CSS below resolves this by detecting user interactions. It differentiates clicks from drag actions, allowing Carousel images to become clickable links only when the user isn't dragging.
Add this to your Site Footer Code Injection area:
<!-- Clickable Image in List Section Carousel from Will-Myers.com -->
<script>
document.addEventListener("DOMContentLoaded", function () {
// Find all list containers for event delegation
const listContainers = document.querySelectorAll(".user-items-list ul");
if (!listContainers.length) return;
// Store click/touch tracking data
let startX, startY, startTime;
const clickThreshold = 10; // pixels
const timeThreshold = 300; // milliseconds
// Function to handle the start of interaction (mouse or touch)
function handleStart(e) {
console.log("handleStart");
// Get coordinates from either mouse or touch event
const clientX = e.clientX || (e.touches && e.touches[0] ? e.touches[0].clientX : null);
const clientY = e.clientY || (e.touches && e.touches[0] ? e.touches[0].clientY : null);
if (clientX === null || clientY === null) return;
// Find the mediaInner element that was clicked/touched or one of its children
const mediaInner = e.target.closest('.user-items-list-carousel__media-inner');
if (!mediaInner) return;
// Store the starting position and time
startX = clientX;
startY = clientY;
startTime = Date.now();
}
// Function to handle the end of interaction (mouse or touch)
function handleEnd(e) {
// Get coordinates from either mouse or touch event
const clientX = e.clientX || (e.changedTouches && e.changedTouches[0] ? e.changedTouches[0].clientX : null);
const clientY = e.clientY || (e.changedTouches && e.changedTouches[0] ? e.changedTouches[0].clientY : null);
if (clientX === null || clientY === null) return;
// Find the mediaInner element that was clicked/touched or one of its children
const mediaInner = e.target.closest('.user-items-list-carousel__media-inner');
if (!mediaInner) return;
const deltaX = Math.abs(clientX - startX);
const deltaY = Math.abs(clientY - startY);
const deltaTime = Date.now() - startTime;
// If movement was minimal and time was short, treat as a click/tap
if (deltaX < clickThreshold && deltaY < clickThreshold && deltaTime < timeThreshold) {
// Find the parent list item
const listItem = mediaInner.closest('li.list-item');
if (!listItem) return;
// Try to find the href from title or button
const titleLink = listItem.querySelector(".list-item-content__title a");
const buttonLink = listItem.querySelector(".list-item-content__button-wrapper a");
// Get the href from whichever link exists
const href = titleLink ? titleLink.getAttribute("href") :
buttonLink ? buttonLink.getAttribute("href") : null;
if (href) {
window.location.href = href;
}
}
}
// Add event listeners to each list container
listContainers.forEach(listContainer => {
// Mouse events
listContainer.addEventListener('mousedown', handleStart);
listContainer.addEventListener('mouseup', handleEnd);
// Touch events
listContainer.addEventListener("touchstart", handleStart);
listContainer.addEventListener("touchend", handleEnd);
});
});
</script>
Add this to your Custom CSS area
/**
* Clickable Image in
* List Section Carousel
* from Will-Myers.com
**/
.user-items-list ul{
.user-items-list-carousel__media-inner{
pointer-events:auto;
}
.user-items-list-carousel__media-inner img {
pointer-events:none;
}
}
(Optional) Hide buttons in List Section Carousel
/**
* Hide Buttons in
* List Section Carousel
* from Will-Myers.com
**/
.user-items-list-carousel{
.list-item-content__button-wrapper{
display: none;
}
}
Let us know in the comments, if this does or doesn’t work for you so we can keep tweaking on this.