Coverflow Carousel
Step 1 — Build the section
Add a section and set it to Auto Layout (List). Add one item per card, each with an image, a title, and a short description. Aim for 5 or more items; the loop rotates more smoothly with a few cards.
Step 2 — Add the Section ID
Give that section this exact ID:
Step 3 — Add the JavaScript
This powers the carousel. Go to:
Settings → Advanced → Code Injection → Footer
Paste the code below and Save. (If you had an older carousel script there, replace it, don't keep both.)
<!-- ===== #class COVERFLOW CAROUSEL — PART A (JavaScript) =====
PASTE IN: Settings -> Advanced -> Code Injection -> FOOTER
(Replace any previous carousel script — don't keep both.)
Scoped to the section whose ID is: class
============================================================= -->
<script>
(function () {
var SWIPER_CSS = "https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css";
var SWIPER_JS = "https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js";
function loadSwiper(cb){
if (window.Swiper) return cb();
if (!document.querySelector('link[data-swiper]')){
var l=document.createElement('link');
l.rel='stylesheet'; l.href=SWIPER_CSS; l.setAttribute('data-swiper','1');
document.head.appendChild(l);
}
var existing=document.querySelector('script[data-swiper]');
if (!existing){
var s=document.createElement('script');
s.src=SWIPER_JS; s.setAttribute('data-swiper','1'); s.onload=cb;
document.body.appendChild(s);
} else {
var t=setInterval(function(){ if(window.Swiper){ clearInterval(t); cb(); } },50);
}
}
function build(){
var section = document.querySelector('#class');
if (!section) return;
var listWrap = section.querySelector('.user-items-list');
var ul = section.querySelector('.user-items-list-item-container');
if (!ul || ul.dataset.cflowReady) return;
if (ul.querySelectorAll('.list-item').length < 2) return; // needs at least a couple of items
ul.dataset.cflowReady = '1';
listWrap.classList.add('swiper');
ul.classList.add('swiper-wrapper');
[].forEach.call(ul.querySelectorAll('.list-item'), function(li){ li.classList.add('swiper-slide'); });
var prev=document.createElement('div');
prev.className='cflow-arrow cflow-prev'; prev.setAttribute('aria-label','Previous'); prev.textContent='‹';
var next=document.createElement('div');
next.className='cflow-arrow cflow-next'; next.setAttribute('aria-label','Next'); next.textContent='›';
var pag=document.createElement('div'); pag.className='cflow-pagination';
listWrap.appendChild(prev); listWrap.appendChild(next); listWrap.appendChild(pag);
new Swiper(listWrap, {
effect:'creative',
grabCursor:true,
centeredSlides:true,
loop:true,
spaceBetween:0,
slidesPerView:3,
watchSlidesProgress:true,
creativeEffect:{
limitProgress:1,
perspective:true,
prev:{ translate:['-82%',0,-280], scale:0.85, opacity:1 }, /* bolder/bigger side cards */
next:{ translate:[ '82%',0,-280], scale:0.85, opacity:1 }
},
navigation:{ nextEl:next, prevEl:prev },
pagination:{ el:pag, clickable:true },
breakpoints:{ 0:{ slidesPerView:1.3 }, 768:{ slidesPerView:3 } }
});
}
function init(){ loadSwiper(build); }
if (document.readyState !== 'loading') init();
else document.addEventListener('DOMContentLoaded', init);
window.addEventListener('load', init);
})();
</script>
Step 4 — Add the CSS
This styles the cards, arrows, and dots. Go to:
Design → Custom CSS (Website → Website Tools → Custom CSS)
Paste the code below and Save.
/* ===== #class — COVERFLOW CARD CAROUSEL — PART B (CSS) =====
PASTE IN: Website -> Website Tools -> Custom CSS
(Replace any previous #class block.) Section ID: class
============================================================= */
/* trim the section's vertical whitespace (top/bottom of the whole section) */
#class{ padding-top:56px !important; padding-bottom:32px !important; }
#class .user-items-list{
overflow:visible !important;
position:relative !important;
width:95vw !important; /* fills most of the screen on wide monitors */
max-width:2000px !important; /* upper limit; raise/lower to taste */
margin:0 auto !important;
padding:16px 0 48px !important; /* space above cards / below for the dots */
}
#class .user-items-list-item-container.swiper-wrapper{
display:flex !important;
grid-template-columns:none !important;
grid-gap:0 !important; gap:0 !important;
padding:0 !important; /* kills Squarespace's side padding that threw off centring */
align-items:center !important;
}
/* the green cards — Swiper sets their width from slidesPerView, so don't force a width here */
#class .list-item.swiper-slide{
background:#156b5b !important; /* card colour */
border-radius:24px !important;
padding:22px 20px !important;
box-sizing:border-box !important;
display:flex !important;
flex-direction:column-reverse !important; /* title/text above the image */
height:auto !important;
margin:0 !important;
}
/* fixed image crop so a tall photo can't stretch a card */
#class .list-item .list-item-media-inner{
padding-bottom:72% !important; /* image height vs width — lower = shorter */
height:0 !important;
border-radius:12px !important;
overflow:hidden !important;
}
#class .list-item .list-item-media-inner img,
#class .list-item .list-image{
position:absolute !important; inset:0 !important;
width:100% !important; height:100% !important;
object-fit:cover !important;
}
/* text — slightly bolder/larger so it holds up on the bigger cards */
#class .list-item-content{ padding:0 0 12px !important; }
#class .list-item-content__title{ color:#fff !important; font-weight:700 !important; margin:0 0 4px !important; font-size:clamp(20px, 1.6vw, 30px) !important; }
#class .list-item-content__description,
#class .list-item-content__description p{ color:#fff !important; }
/* round nav arrows — anchored to the carousel edges, in the side whitespace */
#class .cflow-arrow{
position:absolute !important; top:46% !important; transform:translateY(-50%) !important;
width:50px !important; height:50px !important;
border:1px solid #1a1a1a !important; border-radius:50% !important;
display:flex !important; align-items:center !important; justify-content:center !important;
font-size:24px !important; line-height:1 !important; color:#1a1a1a !important;
background:transparent !important; cursor:pointer !important; z-index:50 !important;
}
#class .cflow-prev{ left:0 !important; right:auto !important; }
#class .cflow-next{ right:0 !important; left:auto !important; }
#class .cflow-arrow:hover{ background:#1a1a1a !important; color:#fff !important; }
/* centred pagination dots */
#class .cflow-pagination{
position:absolute !important; bottom:18px !important; left:0 !important; right:0 !important;
display:flex !important; justify-content:center !important; gap:10px !important; z-index:50 !important;
}
#class .cflow-pagination .swiper-pagination-bullet{
width:8px !important; height:8px !important; background:#1a1a1a !important; opacity:.3 !important; margin:0 !important;
}
#class .cflow-pagination .swiper-pagination-bullet-active{ opacity:1 !important; }
/* mobile: hide arrows (swipe instead), show one card with a peek */
@media (max-width:767px){
#class .cflow-arrow{ display:none; }
}
Make it yours (easy tweaks)
A few values in the CSS / JS you can change:
Card colour → #156b5b in the .swiper-slide rule (CSS).
Image height → padding-bottom:72% on .list-item-media-inner (lower = shorter).
Overall size → width:95vw and max-width:2000px on #class .user-items-list.
Side-card boldness → in the JS, scale:0.85 (raise toward 0.92 for bigger side cards) and the -280 in the translate (closer to 0 = flatter/bolder).
Top/bottom spacing → padding-top / padding-bottom on the #class rule.
Good to know
View the published page (or an incognito tab) to see it move, the editor preview doesn't run the script.
It loads the Swiper library from a CDN automatically, nothing to install.
On phones the arrows hide and you simply swipe.
Done
You get a centred coverflow with equal side cards, arrows in the whitespace, and tidy centred dots. If it sits as a plain list, check the section's ID is exactly class and that both the Footer JS and the CSS are saved.