How to Add a Scrolling Vertical Testimonial Carousel to Squarespace
What This Effect Does
Static testimonial sections sit there doing nothing. Visitors skim past them. A scrolling testimonial carousel creates motion that pulls the eye in and keeps people reading your reviews without any clicking or swiping required.
This effect displays your testimonials in vertical columns that scroll continuously in alternating directions. One column moves up, the next moves down, and the third moves up again. The cards loop seamlessly, the animation pauses when someone hovers over a card, and the whole thing collapses gracefully on mobile. I originally built this for Alexandria Agresta's Squarespace site, and it quickly became one of my most-requested features.
You don't need any plugins or third-party apps. This is pure CSS animation with a small amount of HTML structure. If you can paste code into a Squarespace code block, you can set this up in about ten minutes. Use the configurator below to add your own testimonials and customize every visual detail, or grab the default code further down if you just want the base version.
Step-by-Step Setup
Add a new section
This Squarespace testimonial carousel works on both dark and light backgrounds. In the Squarespace editor, add a new blank section. Open the section settings, go to the Background tab, and set a solid color. The default code uses a dark theme with glassmorphism cards, but you can switch to a light background by adjusting the card, text, and hover colors in the configurator below.
Insert a code block
Click the "+" icon inside your new section and select "Code" from the block menu. This gives you a raw HTML input field. Make sure the "Display Source" toggle is turned OFF. Leaving it on will show your raw code to visitors instead of rendering the carousel.
Generate or copy your code
Use the configurator below to add your own testimonials and customize the design. It generates a complete code block you can copy and paste. If you'd rather start with the defaults, grab the base code from the "Default Code" section further down and replace the placeholder text with your own reviews.
Paste and preview
Paste your code into the code block and save. You should see three columns of cards scrolling vertically. Check the mobile view in Squarespace's device preview to confirm the stacked layout looks right. If the columns feel too fast or too slow, adjust the Scroll Speed in the configurator or change the 45s value in the CSS.
For the best visual result, keep the number of testimonials roughly even across columns. Three to five per column works well. Large differences in card count between columns will cause uneven scroll speeds since each column translates by 50% of its own height.
Style Configurator
Add your own testimonials, customize the design, and copy the complete code block. The default settings are built for dark backgrounds, but you can configure this for light backgrounds just as easily by adjusting the card, text, and hover colors below. The output updates in real time as you type and adjust. Paste the generated code directly into your Squarespace code block.
The generated code automatically duplicates your testimonials inside each column. This is what makes the infinite loop seamless. If you edit the HTML manually later, always keep the duplicate set matching the original set above it.
The Default Code
If you'd rather skip the configurator and start with the base version, copy the code below. Replace each "Your testimonial text here." with your own quotes and you're good to go.
<style>
/* --- Testimonial Marquee Styles --- */
.masonry-scroll-wrapper {
display: flex;
gap: 2rem;
height: 600px;
overflow: hidden;
position: relative;
z-index: 2;
padding: 0 1rem;
mask-image: linear-gradient(to bottom, transparent, black 10%, black 90%, transparent);
-webkit-mask-image: linear-gradient(to bottom, transparent, black 10%, black 90%, transparent);
}
.masonry-col {
flex: 1;
display: flex;
flex-direction: column;
gap: 2rem;
}
.masonry-card {
background: rgba(255,255,255,0.08);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
padding: 2rem;
border: 1px solid rgba(255,255,255,0.1);
color: white;
border-radius: 8px;
transition: transform 0.4s ease, background 0.4s ease,
border-color 0.4s ease, box-shadow 0.4s ease;
will-change: transform;
}
.masonry-card:hover {
transform: scale(1.02);
background: rgba(253,2,182,0.08);
border-color: rgba(253,2,182,0.4);
box-shadow: 0 0 20px rgba(253,2,182,0.15),
inset 0 0 20px rgba(253,2,182,0.05);
}
.masonry-card p {
color: #eee;
font-size: 0.95rem;
font-style: italic;
line-height: 1.6;
margin: 0;
}
@keyframes scrollUp {
0% { transform: translateY(0); }
100% { transform: translateY(-50%); }
}
@keyframes scrollDown {
0% { transform: translateY(-50%); }
100% { transform: translateY(0); }
}
.scroll-up {
animation: scrollUp 45s linear infinite;
}
.scroll-down {
animation: scrollDown 45s linear infinite;
}
.masonry-scroll-wrapper:hover .masonry-col {
animation-play-state: paused;
}
@media (max-width: 768px) {
.masonry-scroll-wrapper {
flex-direction: column;
height: auto;
mask-image: none;
-webkit-mask-image: none;
overflow: visible;
padding: 0;
}
.masonry-col {
animation: none;
gap: 1.5rem;
margin-bottom: 1.5rem;
}
.scroll-up > .masonry-card:nth-child(n+4) { display: none; }
.scroll-down > .masonry-card:nth-child(n+3) { display: none; }
}
</style>
<div class="masonry-scroll-wrapper">
<!-- Column 1: Scrolls Up -->
<div class="masonry-col scroll-up">
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<!-- DUPLICATES FOR SEAMLESS LOOP -->
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
</div>
<!-- Column 2: Scrolls Down -->
<div class="masonry-col scroll-down">
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<!-- DUPLICATES FOR SEAMLESS LOOP -->
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
</div>
<!-- Column 3: Scrolls Up -->
<div class="masonry-col scroll-up">
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<!-- DUPLICATES FOR SEAMLESS LOOP -->
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
<div class="masonry-card"><p>"Your testimonial text here."</p></div>
</div>
</div>
How the Scrolling Marquee Works
If you're curious about the mechanics behind this scrolling testimonial carousel, here's what's happening under the hood.
The trick behind any infinite scrolling effect is duplication. You can't scroll a finite list forever, so you duplicate the testimonial cards inside each column. When the animation reaches the halfway point (where the duplicates begin), it resets to the start. Since the duplicates are identical to the originals, the reset is invisible. The viewer sees one continuous, never-ending scroll.
Each column is a flex container with its cards stacked vertically. A CSS @keyframes animation applies a translateY that moves the column by exactly 50% of its total height. Two animations exist: one that shifts upward (0 to -50%) and one that shifts downward (-50% to 0). Alternating these across columns creates that staggered, organic feel.
The fade at the top and bottom edges comes from a CSS mask-image gradient. This makes cards appear to dissolve into and out of view rather than getting hard-cropped by the container edge. On hover, animation-play-state is set to paused on all columns, so the entire wall freezes when a visitor mouses over any card.
CSS transforms that use translate are handled by the browser's GPU, which makes them extremely efficient. Actual scrolling triggers layout recalculations on every frame. Using translateY with will-change: transform keeps the animation smooth at 60fps with almost zero CPU cost.
Customization Reference
If you prefer editing CSS directly instead of using the configurator, here are the key properties and what they control.
Scroll speed
The 45s value in the .scroll-up and .scroll-down rules controls how many seconds one full loop takes. Lower numbers scroll faster. I find 30s to 60s works for most sites. Anything under 20s feels frantic, and anything over 80s barely looks like it's moving.
Container height
The height: 600px on .masonry-scroll-wrapper determines how tall the visible carousel area is. This should be tall enough to show two or three cards at a time. If your cards have longer text, increase this value.
Card appearance
The background, border, and border-radius on .masonry-card control the glass-card look. The backdrop-filter: blur(5px) creates the frosted glass effect. If you want opaque cards instead, set the background opacity to 1 and remove the backdrop-filter lines.
Hover effect
The .masonry-card:hover rule handles the color shift and glow on hover. The box-shadow property creates the outer and inner glow. Set both glow opacities to 0 if you want a hover color change without any glow. The transform: scale(1.02) adds a subtle zoom on hover. Set it to scale(1) to disable it.
Fade edges
The mask-image gradient on .masonry-scroll-wrapper creates the fade-to-transparent effect at the top and bottom. The 10% and 90% values control where the fade begins and ends. Change these to 5% and 95% for a subtler fade, or remove the mask-image lines entirely for hard edges.
Adding or removing columns
You can use two columns instead of three by removing one of the .masonry-col divs from the HTML. The flex layout will adjust automatically. For two columns, alternate between scroll-up and scroll-down classes. You can add a fourth column the same way, though three tends to be the sweet spot for readability.
Mobile behavior
On screens narrower than 768px, the animation stops and columns stack vertically. The CSS hides extra duplicate cards using :nth-child(n+4) and :nth-child(n+3) selectors. Adjust those numbers to show more or fewer cards on mobile.
FAQ
Does this scrolling testimonials Squarespace carousel work on all templates?
Yes. The code goes into a code block, so it works on any Squarespace 7.1 template and on Squarespace 7.0. The CSS is self-contained and doesn't rely on any template-specific classes. The default style is built for dark backgrounds, but the configurator above lets you adjust the card, text, and hover colors for light backgrounds too.
Will the animation slow down my page?
No. CSS animations using transform are GPU-accelerated, which makes them one of the lightest animation methods available. The will-change: transform property on the cards tells the browser to optimize rendering ahead of time. You won't see any impact on your Squarespace page speed scores.
How many testimonials should I include?
Three to five per column is the sweet spot. Fewer than three makes the loop look repetitive since the duplicate set appears too quickly. More than six works fine but increases the total scroll distance, so you may want to lower the speed value to compensate.
Can I use this on a light background?
Yes. Change the card background to something like rgba(0,0,0,0.05), the border to rgba(0,0,0,0.1), and the text color to a dark value like #333. Update the hover colors accordingly. The configurator above makes this straightforward since you can preview all values before copying.
Can a Squarespace developer help me customize this further?
If you want to add author names and photos to each card, integrate this with other custom sections, or build it into a full testimonials page, the base structure is flexible enough to support all of that. I've built dozens of variations of this carousel for clients. If you'd rather hand it off, feel free to reach out and I can put together something built around your site.
Looking for a refreshed web presence?
Looking for a website that truly represents your brand and drives results? Minimist is a Squarespace designer, specializing in minimal, modern designs that connect with your audience and make an impact. If you have a project in mind, I'd love to hear from you!
Book a Free Consultation