15 CSS Card Grid Layouts04 / 15

Pure CSSMIT licensed

CSS Testimonial Wall Grid

An asymmetric testimonial wall with one featured 2x2 hero quote and 5 supporting testimonial cards — each with customer avatar, name, role, company, star rating, and quote. The exact pattern Vercel, Linear, and Stripe use on their homepages to stack social proof at scale.

Published

Live Demo
Try it

The code

<div class="cg-11">
  <div class="cg-11__head">
    <span class="cg-11__kicker">Customer love</span>
    <h2 class="cg-11__title">2,400+ teams ship faster.</h2>
  </div>
  <div class="cg-11__grid">

    <article class="cg-11__card cg-11__card--featured">
      <div class="cg-11__stars" aria-label="5 of 5 stars">★★★★★</div>
      <blockquote class="cg-11__quote">
        We replaced four tools with one. Our deploys went from 12 minutes to under 90 seconds, and the whole engineering team finally agrees on something. Worth every penny.
      </blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--1"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Maya Chen</span>
          <span class="cg-11__role">VP Engineering · <strong>Linear</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"The onboarding alone saved us a week. We were live in three hours."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--2"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Liam Okonkwo</span>
          <span class="cg-11__role">CTO · <strong>Plaid</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"Honestly the best support team I've worked with in 12 years of building SaaS."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--3"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Aria Patel</span>
          <span class="cg-11__role">Founder · <strong>Resend</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★<span class="cg-11__stars--dim">★</span></div>
      <blockquote class="cg-11__quote">"4 stars only because we keep finding new things we wish it did. It does most of them next quarter."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--4"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Noah Reyes</span>
          <span class="cg-11__role">Eng Lead · <strong>Vercel</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"Our incident response time dropped 73%. Board noticed."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--5"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Zoe Larsson</span>
          <span class="cg-11__role">SRE Manager · <strong>Stripe</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"We tried five alternatives. Came back here on day three."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--6"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Sam Okafor</span>
          <span class="cg-11__role">Product · <strong>Notion</strong></span>
        </div>
      </footer>
    </article>

  </div>
</div>
.cg-11,
.cg-11 *,
.cg-11 *::before,
.cg-11 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cg-11 ::selection {
  background: #0f172a;
  color: #fff;
}

.cg-11 {
  --bg: #f8fafc;
  --card: #ffffff;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --accent: #f59e0b;
  --feat-bg: #0f172a;
  --feat-ink: #f8fafc;
  min-height: 100vh;
  background: var(--bg);
  padding: clamp(32px,4vw,64px) clamp(20px,3vw,48px);
  font-family: -apple-system,BlinkMacSystemFont,"Inter","Segoe UI",sans-serif;
  color: var(--ink);
}

.cg-11__head {
  text-align: center;
  margin-bottom: clamp(32px,4vw,48px);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.cg-11__kicker {
  display: inline-block;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.cg-11__title {
  font-size: clamp(1.8rem,3.4vw,2.6rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
}

.cg-11__grid {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-rows: minmax(200px,auto);
  gap: clamp(14px,1.6vw,20px);
  max-width: 1180px;
  margin: 0 auto;
}

.cg-11__card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: clamp(18px,2vw,24px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 16px;
  transition: transform .25s,box-shadow .25s;
}

.cg-11__card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 28px -14px rgba(15,23,42,.18);
}

.cg-11__card--featured {
  grid-column: span 2;
  grid-row: span 2;
  background: var(--feat-bg);
  color: var(--feat-ink);
  border-color: var(--feat-bg);
}

.cg-11__stars {
  color: var(--accent);
  font-size: .95rem;
  letter-spacing: .1em;
  font-feature-settings: "tnum";
}

.cg-11__stars--dim {
  color: rgba(100,116,139,.4);
}

.cg-11__card--featured .cg-11__stars {
  font-size: 1.1rem;
}

.cg-11__quote {
  font-size: clamp(.94rem,1.05vw,1rem);
  line-height: 1.5;
  color: var(--ink);
}

.cg-11__card--featured .cg-11__quote {
  color: var(--feat-ink);
  font-size: clamp(1.15rem,1.8vw,1.5rem);
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: -.005em;
}

.cg-11__attr {
  display: flex;
  align-items: center;
  gap: 12px;
}

.cg-11__avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex-shrink: 0;
}

.cg-11__card--featured .cg-11__avatar {
  width: 48px;
  height: 48px;
}

.cg-11__avatar--1 {
  background: linear-gradient(135deg,#f9c1cf,#d97a99);
}

.cg-11__avatar--2 {
  background: linear-gradient(135deg,#a7c8e7,#5b8fd9);
}

.cg-11__avatar--3 {
  background: linear-gradient(135deg,#c5da9c,#7aa852);
}

.cg-11__avatar--4 {
  background: linear-gradient(135deg,#f7b88a,#d97f4f);
}

.cg-11__avatar--5 {
  background: linear-gradient(135deg,#c4b5fd,#9b87e5);
}

.cg-11__avatar--6 {
  background: linear-gradient(135deg,#fef0a3,#e6c54a);
}

.cg-11__who {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.cg-11__name {
  font-size: .92rem;
  font-weight: 700;
}

.cg-11__role {
  font-size: .78rem;
  color: var(--muted);
}

.cg-11__card--featured .cg-11__role {
  color: rgba(248,250,252,.65);
}

.cg-11__role strong {
  font-weight: 700;
  color: var(--ink);
}

.cg-11__card--featured .cg-11__role strong {
  color: var(--feat-ink);
}

@media (max-width: 960px) {
  .cg-11__grid {
    grid-template-columns: repeat(2,1fr);
  }

  .cg-11__card--featured {
    grid-column: span 2;
    grid-row: span 1;
  }
}

@media (max-width: 560px) {
  .cg-11__grid {
    grid-template-columns: 1fr;
  }

  .cg-11__card--featured {
    grid-column: span 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cg-11__card {
    transition: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Card Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Testimonial Wall Grid
Source: https://codefronts.com/layouts/css-card-grid-layout/css-testimonial-wall-grid/

An asymmetric testimonial wall with one featured 2x2 hero quote and 5 supporting testimonial cards — each with customer avatar, name, role, company, star rating, and quote. The exact pattern Vercel, Linear, and Stripe use on their homepages to stack social proof at scale.
## HTML
```html
<div class="cg-11">
  <div class="cg-11__head">
    <span class="cg-11__kicker">Customer love</span>
    <h2 class="cg-11__title">2,400+ teams ship faster.</h2>
  </div>
  <div class="cg-11__grid">

    <article class="cg-11__card cg-11__card--featured">
      <div class="cg-11__stars" aria-label="5 of 5 stars">★★★★★</div>
      <blockquote class="cg-11__quote">
        We replaced four tools with one. Our deploys went from 12 minutes to under 90 seconds, and the whole engineering team finally agrees on something. Worth every penny.
      </blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--1"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Maya Chen</span>
          <span class="cg-11__role">VP Engineering · <strong>Linear</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"The onboarding alone saved us a week. We were live in three hours."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--2"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Liam Okonkwo</span>
          <span class="cg-11__role">CTO · <strong>Plaid</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"Honestly the best support team I've worked with in 12 years of building SaaS."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--3"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Aria Patel</span>
          <span class="cg-11__role">Founder · <strong>Resend</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★<span class="cg-11__stars--dim">★</span></div>
      <blockquote class="cg-11__quote">"4 stars only because we keep finding new things we wish it did. It does most of them next quarter."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--4"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Noah Reyes</span>
          <span class="cg-11__role">Eng Lead · <strong>Vercel</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"Our incident response time dropped 73%. Board noticed."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--5"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Zoe Larsson</span>
          <span class="cg-11__role">SRE Manager · <strong>Stripe</strong></span>
        </div>
      </footer>
    </article>

    <article class="cg-11__card">
      <div class="cg-11__stars">★★★★★</div>
      <blockquote class="cg-11__quote">"We tried five alternatives. Came back here on day three."</blockquote>
      <footer class="cg-11__attr">
        <div class="cg-11__avatar cg-11__avatar--6"></div>
        <div class="cg-11__who">
          <span class="cg-11__name">Sam Okafor</span>
          <span class="cg-11__role">Product · <strong>Notion</strong></span>
        </div>
      </footer>
    </article>

  </div>
</div>
```
## CSS
```css
.cg-11,
.cg-11 *,
.cg-11 *::before,
.cg-11 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.cg-11 ::selection {
  background: #0f172a;
  color: #fff;
}

.cg-11 {
  --bg: #f8fafc;
  --card: #ffffff;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --accent: #f59e0b;
  --feat-bg: #0f172a;
  --feat-ink: #f8fafc;
  min-height: 100vh;
  background: var(--bg);
  padding: clamp(32px,4vw,64px) clamp(20px,3vw,48px);
  font-family: -apple-system,BlinkMacSystemFont,"Inter","Segoe UI",sans-serif;
  color: var(--ink);
}

.cg-11__head {
  text-align: center;
  margin-bottom: clamp(32px,4vw,48px);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.cg-11__kicker {
  display: inline-block;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.cg-11__title {
  font-size: clamp(1.8rem,3.4vw,2.6rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.1;
}

.cg-11__grid {
  display: grid;
  grid-template-columns: repeat(4,1fr);
  grid-auto-rows: minmax(200px,auto);
  gap: clamp(14px,1.6vw,20px);
  max-width: 1180px;
  margin: 0 auto;
}

.cg-11__card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: clamp(18px,2vw,24px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 16px;
  transition: transform .25s,box-shadow .25s;
}

.cg-11__card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 28px -14px rgba(15,23,42,.18);
}

.cg-11__card--featured {
  grid-column: span 2;
  grid-row: span 2;
  background: var(--feat-bg);
  color: var(--feat-ink);
  border-color: var(--feat-bg);
}

.cg-11__stars {
  color: var(--accent);
  font-size: .95rem;
  letter-spacing: .1em;
  font-feature-settings: "tnum";
}

.cg-11__stars--dim {
  color: rgba(100,116,139,.4);
}

.cg-11__card--featured .cg-11__stars {
  font-size: 1.1rem;
}

.cg-11__quote {
  font-size: clamp(.94rem,1.05vw,1rem);
  line-height: 1.5;
  color: var(--ink);
}

.cg-11__card--featured .cg-11__quote {
  color: var(--feat-ink);
  font-size: clamp(1.15rem,1.8vw,1.5rem);
  line-height: 1.35;
  font-weight: 500;
  letter-spacing: -.005em;
}

.cg-11__attr {
  display: flex;
  align-items: center;
  gap: 12px;
}

.cg-11__avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex-shrink: 0;
}

.cg-11__card--featured .cg-11__avatar {
  width: 48px;
  height: 48px;
}

.cg-11__avatar--1 {
  background: linear-gradient(135deg,#f9c1cf,#d97a99);
}

.cg-11__avatar--2 {
  background: linear-gradient(135deg,#a7c8e7,#5b8fd9);
}

.cg-11__avatar--3 {
  background: linear-gradient(135deg,#c5da9c,#7aa852);
}

.cg-11__avatar--4 {
  background: linear-gradient(135deg,#f7b88a,#d97f4f);
}

.cg-11__avatar--5 {
  background: linear-gradient(135deg,#c4b5fd,#9b87e5);
}

.cg-11__avatar--6 {
  background: linear-gradient(135deg,#fef0a3,#e6c54a);
}

.cg-11__who {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.cg-11__name {
  font-size: .92rem;
  font-weight: 700;
}

.cg-11__role {
  font-size: .78rem;
  color: var(--muted);
}

.cg-11__card--featured .cg-11__role {
  color: rgba(248,250,252,.65);
}

.cg-11__role strong {
  font-weight: 700;
  color: var(--ink);
}

.cg-11__card--featured .cg-11__role strong {
  color: var(--feat-ink);
}

@media (max-width: 960px) {
  .cg-11__grid {
    grid-template-columns: repeat(2,1fr);
  }

  .cg-11__card--featured {
    grid-column: span 2;
    grid-row: span 1;
  }
}

@media (max-width: 560px) {
  .cg-11__grid {
    grid-template-columns: 1fr;
  }

  .cg-11__card--featured {
    grid-column: span 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cg-11__card {
    transition: none;
  }
}
```

How this works

The grid uses grid-template-columns: repeat(4, 1fr) with grid-auto-rows: minmax(220px, auto). The featured testimonial gets grid-column: span 2; grid-row: span 2 so it occupies a 2x2 block at scale — the visual anchor that makes the wall feel intentional rather than a wall of equal blocks.

Each card uses Flexbox column with justify-content: space-between so the quote text floats at the top and the attribution (avatar + name + role) pins to the bottom regardless of quote length. Star ratings use 5 Unicode stars (★) with the first N filled via color: var(--accent) and the rest dimmed via color: var(--line) — no SVG, no icon font.

Customer avatars are circular CSS-gradient placeholders (linear-gradient(135deg, c1, c2)) sized at 40px — production code would swap these for real avatar URLs, but the gradient version means the demo ships zero image dependencies and every avatar has a consistent visual feel.

Make it yours

  • Recolour the brand accent (used on stars and featured-card border) by editing --accent on .cg-11.
  • Change the featured testimonial position by moving the .cg-11__card--featured class — try the corner positions for varied wall feel.
  • Swap CSS-gradient avatars for real images by replacing each .cg-11__avatar div with an <img> tag.
  • Add company logos by inserting a small SVG inline next to the company name in .cg-11__company.
  • Resize the wall by changing grid-auto-rows: minmax(220px, auto) — 280px gives more reading room, 180px tightens the wall.

Gotchas — read before shipping

  • At narrow viewports the 2x2 featured tile can dominate the layout — the mobile breakpoint forces all cards back to 1-column with featured first, but make sure your real testimonial quote isn't so long it overwhelms the mobile read.
  • Star ratings with Unicode glyphs (★ U+2605) render at slightly different baselines across system fonts — if you see vertical misalignment, set font-feature-settings: 'tnum' on the rating container.
  • Avatar gradients are decorative placeholders; if you swap to real images, add object-fit: cover and aspect-ratio: 1 to .cg-11__avatar img to keep circular framing.

Browser support

ChromeSafariFirefoxEdge
57+10.1+52+57+

All baseline CSS Grid + Flexbox. Unicode star (U+2605) and CSS gradients have universal browser support.

Techniques used in this demo

Search CodeFronts

Loading…