Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Elastic Column Testimonials Block for React Aria

Three long stories from Fieldnote's customers in elastic columns inside one framed figure: the story you hover or focus widens while the others give way, and each clamped quote opens in full.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

A row of three testimonial stories whose columns stretch, for React with React Aria. The row is one framed figure, with + marks on its corners and a hairline between the stories. At rest the three share the row equally. Point at one, or Tab into it, and its column grows to 1.6 parts while the other two give way, with the grid's grid-template-columns transitioning in CSS and a quiet tint under the story you are on. Each story shows a quote clamped to five lines with a "Full quote" button that opens it in full, an initials avatar and a caption. Quotes are long enough to fill the clamp in every state, so the stories keep their height while the columns move. Below the lg breakpoint the stories stack with a line between them and nothing stretches. A Shine Button in the header links to all the stories. It's built from Avatar, Button, Guides and Shine Button, with CSS transitions only and your theme's tokens. For landing pages with three substantial stories where the visitor decides which one to read.

FAQ

How do the columns stretch?

The list is a CSS grid with three equal columns from lg. A has() rule on it notices which story is hovered or contains the keyboard focus and swaps the track list, for instance from 1fr 1fr 1fr to 1.6fr 1fr 1fr. The grid-template-columns change is a CSS transition, so it needs no script. The rules live in the ELASTIC string at the top of the file; change the 1.6fr for a stronger or gentler stretch.

Can I use it with a keyboard or on a touch screen?

Yes. Each story holds a "Full quote" button, so Tab lands inside it and the same rule widens it for as long as focus is there. On a touch screen there's no hover, so the stories stay equal and the button still opens the quote in full. Browsers without has() support simply keep the equal columns.

How does the full-quote button work?

It toggles aria-expanded and removes the five-line clamp from that story's quote; its chevron turns over. Each story opens on its own, and the button's name includes the speaker ("Full quote from Nandi Dlamini"). Opening a story makes it, and its row, taller by design; nothing else moves sideways.

What happens with reduced motion?

The columns don't stretch at all: the three stay equal and nothing animates, including the chevron, the tint and the entrance. The button still opens the quote, and the Shine Button's light only fades in.

How do screen readers read it?

The section's heading is an h2 and the stories are the items of a list named "Customer stories", each a figure with a blockquote and a figcaption. The clamp only hides overflow visually, so a screen reader reads each quote in full whether or not it's opened. The quote sits in a bdi, so its marks stay put in right-to-left languages.

How does it fit on a phone?

Below lg the stories stack in one column inside the frame, each as wide as the screen with a hairline above it, and no column stretches. The header's button sits under the text, so the first story starts on the first screen. Nothing has a fixed height or width, so the stories hold their quotes down to 320 px.