Home / Snippets / Layout /

Testimonial card with CQ

Responsive testimonial using container queries — adapts layout based on container width, not viewport.

This product transformed how our team collaborates. The container query implementation is flawless.
JS
Jordan Smith Product Manager @ TechCorp

Narrow container (<20rem)

This product transformed how our team collaborates. The container query implementation is flawless.
JS
Jordan Smith Product Manager @ TechCorp

Wide container (≥20rem)

Widely supported
layoutno-js

Quick implementation

/* HTML: <div class="cq-container"><div class="testimonial-card">...</div></div> */

.cq-container {
  container-type: inline-size;
  container-name: testimonial;
}

.testimonial-card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem;
}

/* Container query: when container width ≥ 20rem */
@container testimonial (min-width: 20rem) {
  .testimonial-card {
    flex-direction: row;
    align-items: flex-start;
  }
  .testimonial-content {
    flex: 1;
  }
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in modern CSS.

Goal: Build a testimonial card component that adapts its layout based on container width using container queries.

Technical constraints:
- Use container-type: inline-size on the wrapper with a named container (e.g., container-name: testimonial).
- Use @container queries to trigger layout changes at specific breakpoints (e.g., min-width: 20rem).
- Use oklch() for all colors instead of rgba() or hex.
- The card should have: quote block, author avatar, name, role/title, and optional star rating.
- Include a flexbox layout that switches from column to row based on container width.

Framework variant (pick one):
A) Vanilla HTML + CSS only — return the .testimonial-card class with container query breakpoints.
B) React component — accept quote, author, role, avatarUrl, rating props; container query in CSS module.

Edge cases to handle:
- Provide a fallback for browsers without container query support (e.g., always use column layout via @supports).
- Handle long names/roles that might overflow on narrow containers with text-overflow or flexible sizing.
- Accessibility: ensure blockquote is semantic, add aria-label to star rating if using spans.

Return the HTML structure and CSS, clearly separated with comments.

Why this matters in 2026

Container queries shift the paradigm from viewport-based to container-based responsiveness. Before container queries, you needed media queries tied to min-width breakpoints, which broke when a component was reused in different contexts. Now, a testimonial card can adapt based on its own container's width, making it truly composable across any layout.

This is especially powerful for design systems: one component, multiple layouts, zero JavaScript. The card knows its context and responds accordingly.

The logic

Set container-type: inline-size on the wrapper to establish a container. Name it with container-name: testimonial for clarity. Inside the card's CSS, use @container testimonial (min-width: 20rem) to apply styles only when the container meets that width. The flex-direction switches from column to row, reflowing the content without media queries.

Unlike media queries, container queries respond to the element's actual context, not the viewport. A card in a sidebar stays narrow; the same card in a main area becomes wide.

Accessibility & performance

Use semantic <blockquote> for the quote text. For star ratings, consider aria-label or visually hidden text to convey the rating to screen readers. Container queries are performant: they're computed during layout, not repaint, and don't trigger reflows. For older browsers, provide a graceful fallback (the base styles without container queries) so the component remains functional.

Browser support note: Container queries landed in all major browsers in 2022-2023. For Safari 15.4+, use the @supports (container-type: inline-size) feature query to test support.