shadcn.io is not affiliated with official shadcn/ui
Testimonials Film Strip Block for Radix UI
A reel of quote cells of different widths in one sideways scroll area: hairlines between the cells, frame numbers, an always-visible scrollbar, faded edges, gentle snapping and a Shine Button in the header.
Installation
Overview
A testimonials block that lets every customer take the room they need, for React with Radix UI. A compact header (a heading, one sentence and a Shine Button) sits above a single strip of quote cells in a horizontal scroll area. A short one-liner is set large in a narrow cell, a medium quote gets a wider one and a long story the widest, all the same height, each with a frame number ("03 / 08"), the author's avatar, name, role and company. The cells share hairlines under one pair of rules that run the strip's length, with + marks where they meet the page's side lines. The scrollbar is drawn on a visible track so visitors can see there is more, the edges fade out, and the cells snap gently into place when the scroll settles. There are no arrows and nothing moves on its own. It's built from Scroll Area, Avatar and Shine Button with your theme's tokens only, and CSS transitions for the entrance. For homepages and pricing pages with a mix of one-line praise and longer stories, where a grid of equal cards would waste room or cut the long ones.
FAQ
How do I add quotes or change a cell's width?
Edit FRAMES at the top of the file: each entry has a quote, the person's name, role, company and initials, and a length of "short", "medium" or "long". The SIZES table next to it turns the length into a cell width (16, 20 or 26rem) and a quote size, so you can retune all three in one place. Pick the length by the quote: a line or two reads best large in a narrow cell, and a paragraph reads best small in a wide one. Give each frame a unique name, since it keys the cell. The frame counter ("03 / 08") follows the length of the list.
Is the scrollbar always visible?
type="auto", so the horizontal one shows whenever the strip overflows, on a muted track with a thumb in the muted foreground colour so it stands out on any theme.How does it work with a keyboard and a screen reader?
The strip is a focusable scroll area, so Tab moves focus into it and the left and right arrow keys scroll it, with a focus ring while it has focus. The cells hold no links or buttons, so there is nothing else to tab through. They snap with snap-proximity, which settles on a cell only when the scroll ends close to one, so it never fights the arrow keys or a drag. A screen reader hears a list named "Customer quotes, side by side"; each quote is a blockquote inside a figure with the author as the caption, and the frame number and the avatar are hidden as decoration. Every cell is on the page, so they are all read in order.
How does it fit a phone?
Below md a cell never grows past 85% of the screen, so the next one always peeks in from the edge, which is the cue to swipe. The header stacks with the button under the sentence, and the strip scrolls sideways with the same snapping. Nothing stacks into a long page, however many quotes you add.
Where does the button go?
It's a link (href="#"): point it at your reel, case studies or sign-up page. It's the block's only primary control, and it sits in the header row, so the strip below carries no buttons.
The button takes asChild with the link inside, so it can be your router's link.
What changes with reduced motion, and what about right-to-left?
The header and the strip appear without their entrance, and the button's sweep of light becomes a fade. Scrolling is the browser's own, so it follows the visitor's settings. In a right-to-left page the strip starts at the right, the first cell is on the right, the fades swap sides and the frame numbers and quotes align to the right.