<div><span class="lbl">CSS marquee that pauses on hover, focus and a switch</span>
<section class="mq" aria-labelledby="mq-title">
<div class="mq-head">
<div><p class="mq-kicker">Heard on the community board</p><h2 id="mq-title">What 3,000 studios say about Atelier</h2></div>
<label class="mq-pause"><input class="mq-toggle sr-only" type="checkbox" role="switch"><span class="mq-sw" aria-hidden="true"></span>Pause scrolling</label>
</div>
<div class="mq-rows">
<div class="mq-row" tabindex="0" role="region" aria-label="Customer quotes, row 1">
<div class="mq-track">
<ul class="mq-list" role="list">
<li><figure class="mq-card"><blockquote><p>Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Presentation mode is the only one our sales team will use.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
<ul class="mq-list" aria-hidden="true">
<li><figure class="mq-card"><blockquote><p>Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Presentation mode is the only one our sales team will use.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
</div>
</div>
<div class="mq-row mq-row--rev" tabindex="0" role="region" aria-label="Customer quotes, row 2">
<div class="mq-track">
<ul class="mq-list" role="list">
<li><figure class="mq-card"><blockquote><p>We run a forty-person studio on it across three time zones.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Students learn it in a single class period.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Comments resolve themselves when the change ships.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>The first design tool our copywriters open without being asked.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
<ul class="mq-list" aria-hidden="true">
<li><figure class="mq-card"><blockquote><p>We run a forty-person studio on it across three time zones.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Students learn it in a single class period.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>Comments resolve themselves when the change ships.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li><figure class="mq-card"><blockquote><p>The first design tool our copywriters open without being asked.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
</div>
</div>
</div>
</section></div>
<div><span class="lbl">Container query card: the same markup, wide and narrow</span>
<div class="cq-demo">
<div class="cq"><figure class="cq-card">
<blockquote><p>We used to keep a spreadsheet of who approved which layout. Now the approval sits on the frame itself, with a name and a date, and the spreadsheet is gone.</p></blockquote>
<p class="cq-meta">Studio plan · since 2023</p>
<figcaption><span class="cq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><span class="cq-name">Yara Haddad</span><span class="cq-role">Head of Design, Olive & Ink</span></span></figcaption>
</figure></div>
<div class="cq"><figure class="cq-card">
<blockquote><p>The free plan carried us through our first year. We upgraded the day we hired a second designer.</p></blockquote>
<p class="cq-meta">Team plan · since 2024</p>
<figcaption><span class="cq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><span class="cq-name">Felix Wagner</span><span class="cq-role">Founder, Wagner Type</span></span></figcaption>
</figure></div>
<div class="cq"><figure class="cq-card">
<blockquote><p>Our interns ship real work in their first week, because everything they need is on one board.</p></blockquote>
<p class="cq-meta">Studio plan · since 2022</p>
<figcaption><span class="cq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><span class="cq-name">Maya Torres</span><span class="cq-role">Design Ops, Brightside Media</span></span></figcaption>
</figure></div>
</div></div>
CSS
/* Modern CSS testimonials.
1. Marquee: two rows of quotes move with a CSS animation, no script. Each list is printed twice
(the copy is aria-hidden) so translateX(-50%) loops seamlessly. Hover, keyboard focus or the
Pause switch (:has()) stops it; under prefers-reduced-motion it does not move at all and each row
becomes a normal horizontal scroller.
2. Container query card: the same markup lays itself out by the width of its container, not the screen. */
.mq{--mq-ink:#1e1b4b;--mq-muted:#4c4a6b;--mq-line:#ddd6fe;--mq-accent:#6d28d9;--mq-speed:46s}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.mq-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:16px 24px;margin-bottom:28px}
.mq-kicker{font-size:.8rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--mq-accent)}
.mq h2{margin-top:6px;font-size:clamp(1.5rem,1.1rem + 1.5vw,2.1rem);font-weight:800;line-height:1.15;letter-spacing:-.02em;color:var(--mq-ink)}
.mq-pause{display:inline-flex;align-items:center;gap:10px;font-size:.9rem;font-weight:600;color:var(--mq-ink);cursor:pointer}
.mq-sw{position:relative;width:40px;height:24px;border-radius:999px;background:#7c7a99;transition:background-color .2s}
.mq-sw::before{content:"";position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:transform .2s}
.mq-toggle:checked+.mq-sw{background:var(--mq-accent)}
.mq-toggle:checked+.mq-sw::before{transform:translateX(16px)}
.mq-toggle:focus-visible+.mq-sw{outline:3px solid var(--mq-accent);outline-offset:3px}
.mq-rows{display:grid;gap:16px}
.mq-row{overflow:hidden;padding:4px 0;border-radius:16px;
-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.mq-row:focus-visible{outline:3px solid var(--mq-accent);outline-offset:2px}
.mq-track{display:flex;width:max-content;animation:mq-scroll var(--mq-speed) linear infinite}
.mq-row--rev .mq-track{animation-direction:reverse}
.mq-rows:hover .mq-track,.mq-rows:focus-within .mq-track,.mq:has(.mq-toggle:checked) .mq-track{animation-play-state:paused}
.mq-list{display:flex;gap:16px;margin:0;padding:0 16px 0 0;list-style:none}
.mq-list>li{display:flex;width:300px}
.mq-card{flex:1;display:flex;flex-direction:column;justify-content:space-between;gap:14px;margin:0;padding:18px 20px;
background:#fff;border:1px solid var(--mq-line);border-radius:16px}
.mq-card blockquote{margin:0;font-size:.95rem;line-height:1.55;color:var(--mq-ink)}
.mq-card figcaption{display:flex;align-items:center;gap:10px;font-size:.85rem;line-height:1.3;color:var(--mq-muted)}
.mq-card figcaption strong{display:block;color:var(--mq-ink)}
.mq-av{flex:none;width:30px;height:30px;border-radius:50%;background:var(--av)}
@keyframes mq-scroll{to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
.mq-track{animation:none}
.mq-list[aria-hidden]{display:none}
.mq-row{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
.mq-pause{display:none}
.mq-sw,.mq-sw::before{transition:none}
}
/* Container query card */
.cq-demo{display:grid;gap:20px}
@media (min-width:768px){.cq-demo{grid-template-columns:1fr 1fr}.cq-demo>:first-child{grid-column:1/-1}}
.cq{container-type:inline-size}
.cq-card{display:grid;gap:16px;height:100%;margin:0;padding:22px;background:#fff;border:1px solid #ddd6fe;border-radius:20px;color:#1e1b4b}
.cq-card blockquote{margin:0;line-height:1.6;text-wrap:pretty}
.cq-card figcaption{display:flex;align-items:center;gap:12px;grid-row:1}
.cq-av{flex:none;width:44px;height:44px;border-radius:14px;background:var(--av)}
.cq-name{display:block;font-weight:700}
.cq-role{display:block;font-size:.875rem;color:#4c4a6b}
.cq-meta{font-size:.8rem;font-weight:600;color:#5b21b6}
@container (min-width:560px){
.cq-card{grid-template-columns:170px 1fr;grid-template-rows:1fr auto;column-gap:32px;padding:32px;
background:linear-gradient(120deg,#f5f3ff,#fff 60%)}
.cq-card figcaption{grid-column:1;grid-row:1 / span 2;align-self:center;flex-direction:column;align-items:flex-start;gap:14px}
.cq-av{width:96px;height:96px;border-radius:28px}
.cq-card blockquote,.cq-meta{grid-column:2}
.cq-card blockquote{align-self:end}
.cq-meta{align-self:start}
.cq-card blockquote{font-size:1.3rem;font-weight:500;line-height:1.45}
}
Bootstrap 5 code
Requires: Bootstrap 5.3.8 CSS
HTML
<div><span class="lbl">CSS marquee that pauses on hover, focus and a switch</span>
<section class="mq" aria-labelledby="mq-title">
<div class="mq-head">
<div><p class="mq-kicker mb-0">Heard on the community board</p><h2 id="mq-title" class="mb-0">What 3,000 studios say about Atelier</h2></div>
<div class="form-check form-switch mq-pause"><input class="form-check-input" type="checkbox" role="switch" id="mq-pause"><label class="form-check-label" for="mq-pause">Pause scrolling</label></div>
</div>
<div class="mq-rows">
<div class="mq-row" tabindex="0" role="region" aria-label="Customer quotes, row 1">
<div class="mq-track">
<ul class="mq-list" role="list">
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Presentation mode is the only one our sales team will use.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
<ul class="mq-list" aria-hidden="true">
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Presentation mode is the only one our sales team will use.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
</div>
</div>
<div class="mq-row mq-row--rev" tabindex="0" role="region" aria-label="Customer quotes, row 2">
<div class="mq-track">
<ul class="mq-list" role="list">
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">We run a forty-person studio on it across three time zones.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Students learn it in a single class period.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Comments resolve themselves when the change ships.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">The first design tool our copywriters open without being asked.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
<ul class="mq-list" aria-hidden="true">
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">We run a forty-person studio on it across three time zones.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><strong>Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption><span class="mq-av" style="--av:radial-gradient(circle,#fde68a 0 32%,#e11d48 33% 100%)" aria-hidden="true"></span><span><strong>Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Students learn it in a single class period.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><strong>Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">Comments resolve themselves when the change ships.</p></blockquote><figcaption><span class="mq-av" style="--av:conic-gradient(from 45deg,#1e1b4b 0 25%,#a78bfa 0 50%,#1e1b4b 0 75%,#a78bfa 0)" aria-hidden="true"></span><span><strong>Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li><figure class="card mq-card mb-0"><blockquote class="mb-0"><p class="mb-0">The first design tool our copywriters open without being asked.</p></blockquote><figcaption><span class="mq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><strong>Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
</div>
</div>
</div>
</section></div>
<div><span class="lbl">Container query card: the same markup, wide and narrow</span>
<div class="cq-demo">
<div class="cq"><figure class="card cq-card mb-0">
<blockquote class="mb-0"><p class="mb-0">We used to keep a spreadsheet of who approved which layout. Now the approval sits on the frame itself, with a name and a date, and the spreadsheet is gone.</p></blockquote>
<p class="cq-meta mb-0">Studio plan · since 2023</p>
<figcaption><span class="cq-av" style="--av:conic-gradient(from 210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)" aria-hidden="true"></span><span><span class="cq-name">Yara Haddad</span><span class="cq-role">Head of Design, Olive & Ink</span></span></figcaption>
</figure></div>
<div class="cq"><figure class="card cq-card mb-0">
<blockquote class="mb-0"><p class="mb-0">The free plan carried us through our first year. We upgraded the day we hired a second designer.</p></blockquote>
<p class="cq-meta mb-0">Team plan · since 2024</p>
<figcaption><span class="cq-av" style="--av:linear-gradient(135deg,#14b8a6 0 50%,#134e4a 50% 100%)" aria-hidden="true"></span><span><span class="cq-name">Felix Wagner</span><span class="cq-role">Founder, Wagner Type</span></span></figcaption>
</figure></div>
<div class="cq"><figure class="card cq-card mb-0">
<blockquote class="mb-0"><p class="mb-0">Our interns ship real work in their first week, because everything they need is on one board.</p></blockquote>
<p class="cq-meta mb-0">Studio plan · since 2022</p>
<figcaption><span class="cq-av" style="--av:radial-gradient(circle at 30% 30%,#c4b5fd 0 28%,transparent 29%),linear-gradient(135deg,#4338ca,#0ea5e9)" aria-hidden="true"></span><span><span class="cq-name">Maya Torres</span><span class="cq-role">Design Ops, Brightside Media</span></span></figcaption>
</figure></div>
</div></div>
CSS
/* Modern CSS testimonials (Bootstrap): .card for the quotes, .form-switch for the Pause control.
Bootstrap has no marquee or container queries, so those parts are the same CSS as the plain version.
1. Marquee: two rows of quotes move with a CSS animation, no script. Each list is printed twice
(the copy is aria-hidden) so translateX(-50%) loops seamlessly. Hover, keyboard focus or the
Pause switch (:has()) stops it; under prefers-reduced-motion it does not move at all and each row
becomes a normal horizontal scroller.
2. Container query card: the same markup lays itself out by the width of its container, not the screen. */
.mq{--mq-ink:#1e1b4b;--mq-muted:#4c4a6b;--mq-line:#ddd6fe;--mq-accent:#6d28d9;--mq-speed:46s}
.mq-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:16px 24px;margin-bottom:28px}
.mq-kicker{font-size:.8rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--mq-accent)}
.mq h2{margin-top:6px;font-size:clamp(1.5rem,1.1rem + 1.5vw,2.1rem);font-weight:800;line-height:1.15;letter-spacing:-.02em;color:var(--mq-ink)}
.mq-pause{display:inline-flex;align-items:center;gap:10px;font-size:.9rem;font-weight:600;color:var(--mq-ink);cursor:pointer}
.mq-pause.form-switch{min-height:0;margin:0;padding:0}
.mq-pause .form-check-input{width:40px;height:24px;margin:0;float:none;border:0;cursor:pointer;background-color:#7c7a99;
--bs-form-switch-bg:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-12 -12 24 24'><circle r='9' fill='%23fff'/></svg>")}
.mq-pause .form-check-input:checked{background-color:var(--mq-accent)}
.mq-pause .form-check-input:focus{box-shadow:none}
.mq-pause .form-check-input:focus-visible{outline:3px solid var(--mq-accent);outline-offset:3px}
.mq-pause .form-check-label{cursor:pointer}
.mq-rows{display:grid;gap:16px}
.mq-row{overflow:hidden;padding:4px 0;border-radius:16px;
-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.mq-row:focus-visible{outline:3px solid var(--mq-accent);outline-offset:2px}
.mq-track{display:flex;width:max-content;animation:mq-scroll var(--mq-speed) linear infinite}
.mq-row--rev .mq-track{animation-direction:reverse}
.mq-rows:hover .mq-track,.mq-rows:focus-within .mq-track,.mq:has(.mq-pause :checked) .mq-track{animation-play-state:paused}
.mq-list{display:flex;gap:16px;margin:0;padding:0 16px 0 0;list-style:none}
.mq-list>li{display:flex;width:300px}
.mq-card{--bs-card-spacer-y:18px;--bs-card-spacer-x:20px;--bs-card-border-color:var(--mq-line);--bs-card-border-radius:16px;
flex:1;justify-content:space-between;gap:14px;padding:18px 20px}
.mq-card blockquote{margin:0;font-size:.95rem;line-height:1.55;color:var(--mq-ink)}
.mq-card figcaption{display:flex;align-items:center;gap:10px;font-size:.85rem;line-height:1.3;color:var(--mq-muted)}
.mq-card figcaption strong{display:block;color:var(--mq-ink)}
.mq-av{flex:none;width:30px;height:30px;border-radius:50%;background:var(--av)}
@keyframes mq-scroll{to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
.mq-track{animation:none}
.mq-list[aria-hidden]{display:none}
.mq-row{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
.mq-pause{display:none}
.mq-pause .form-check-input{transition:none}
}
/* Container query card */
.cq-demo{display:grid;gap:20px}
@media (min-width:768px){.cq-demo{grid-template-columns:1fr 1fr}.cq-demo>:first-child{grid-column:1/-1}}
.cq{container-type:inline-size}
.cq-card{--bs-card-border-color:#ddd6fe;--bs-card-border-radius:20px;display:grid;gap:16px;height:100%;padding:22px;color:#1e1b4b}
.cq-card blockquote{margin:0;line-height:1.6;text-wrap:pretty}
.cq-card figcaption{display:flex;align-items:center;gap:12px;grid-row:1}
.cq-av{flex:none;width:44px;height:44px;border-radius:14px;background:var(--av)}
.cq-name{display:block;font-weight:700}
.cq-role{display:block;font-size:.875rem;color:#4c4a6b}
.cq-meta{font-size:.8rem;font-weight:600;color:#5b21b6}
@container (min-width:560px){
.cq-card{grid-template-columns:170px 1fr;grid-template-rows:1fr auto;column-gap:32px;padding:32px;
background:linear-gradient(120deg,#f5f3ff,#fff 60%)}
.cq-card figcaption{grid-column:1;grid-row:1 / span 2;align-self:center;flex-direction:column;align-items:flex-start;gap:14px}
.cq-av{width:96px;height:96px;border-radius:28px}
.cq-card blockquote,.cq-meta{grid-column:2}
.cq-card blockquote{align-self:end}
.cq-meta{align-self:start}
.cq-card blockquote{font-size:1.3rem;font-weight:500;line-height:1.45}
}
Tailwind 4 code
Requires: Tailwind CSS 4
HTML
<div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#4c4a6b] uppercase">CSS marquee that pauses on hover, focus and a switch</span>
<section class="group/mq" aria-labelledby="mq-title">
<div class="mb-7 flex flex-wrap items-end justify-between gap-x-6 gap-y-4">
<div><p class="text-[.8rem] font-bold tracking-[.12em] text-[#6d28d9] uppercase">Heard on the community board</p><h2 id="mq-title" class="mt-1.5 text-[clamp(1.5rem,1.1rem+1.5vw,2.1rem)] leading-[1.15] font-extrabold tracking-[-.02em] text-[#1e1b4b]">What 3,000 studios say about Atelier</h2></div>
<label class="inline-flex cursor-pointer items-center gap-2.5 text-[.9rem] font-semibold text-[#1e1b4b] motion-reduce:hidden"><input class="mq-toggle peer sr-only" type="checkbox" role="switch"><span class="relative h-6 w-10 rounded-full bg-[#7c7a99] transition-colors duration-200 peer-checked:bg-[#6d28d9] peer-focus-visible:outline-3 peer-focus-visible:outline-offset-3 peer-focus-visible:outline-[#6d28d9] motion-reduce:transition-none before:absolute before:top-[3px] before:left-[3px] before:size-[18px] before:rounded-full before:bg-white before:transition-transform before:duration-200 before:content-[''] peer-checked:before:translate-x-4 motion-reduce:before:transition-none" aria-hidden="true"></span>Pause scrolling</label>
</div>
<div class="group/rows grid gap-4">
<div class="overflow-hidden rounded-2xl py-1 [mask-image:linear-gradient(90deg,transparent,#000_6%,#000_94%,transparent)] focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-[#6d28d9] motion-reduce:overflow-x-auto motion-reduce:[mask-image:none]" tabindex="0" role="region" aria-label="Customer quotes, row 1">
<div class="flex w-max animate-marquee group-hover/rows:[animation-play-state:paused] group-focus-within/rows:[animation-play-state:paused] group-has-[.mq-toggle:checked]/mq:[animation-play-state:paused] motion-reduce:animate-none">
<ul class="flex gap-4 pr-4" role="list">
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle_at_30%_30%,#c4b5fd_0_28%,transparent_29%),linear-gradient(135deg,#4338ca,#0ea5e9)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[linear-gradient(135deg,#14b8a6_0_50%,#134e4a_50%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Presentation mode is the only one our sales team will use.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle,#fde68a_0_32%,#e11d48_33%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_45deg,#1e1b4b_0_25%,#a78bfa_0_50%,#1e1b4b_0_75%,#a78bfa_0)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
<ul class="flex gap-4 pr-4 motion-reduce:hidden" aria-hidden="true">
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Feedback rounds went from email chains to comments on the canvas.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Sara Lindgren</strong>Art director</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Our clients finally stopped sending screenshots of screenshots.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle_at_30%_30%,#c4b5fd_0_28%,transparent_29%),linear-gradient(135deg,#4338ca,#0ea5e9)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Diego Navarro</strong>Freelance designer</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Version history saved a pitch at two in the morning. Enough said.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[linear-gradient(135deg,#14b8a6_0_50%,#134e4a_50%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Chloé Martin</strong>Design lead</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Presentation mode is the only one our sales team will use.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle,#fde68a_0_32%,#e11d48_33%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Ifeoma Obi</strong>Brand manager</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Handing off to developers takes a link, not a meeting.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_45deg,#1e1b4b_0_25%,#a78bfa_0_50%,#1e1b4b_0_75%,#a78bfa_0)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Tariq Aziz</strong>Product designer</span></figcaption></figure></li>
</ul>
</div>
</div>
<div class="overflow-hidden rounded-2xl py-1 [mask-image:linear-gradient(90deg,transparent,#000_6%,#000_94%,transparent)] focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-[#6d28d9] motion-reduce:overflow-x-auto motion-reduce:[mask-image:none]" tabindex="0" role="region" aria-label="Customer quotes, row 2">
<div class="flex w-max animate-marquee group-hover/rows:[animation-play-state:paused] group-focus-within/rows:[animation-play-state:paused] group-has-[.mq-toggle:checked]/mq:[animation-play-state:paused] motion-reduce:animate-none [animation-direction:reverse]">
<ul class="flex gap-4 pr-4" role="list">
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>We run a forty-person studio on it across three time zones.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle_at_30%_30%,#c4b5fd_0_28%,transparent_29%),linear-gradient(135deg,#4338ca,#0ea5e9)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle,#fde68a_0_32%,#e11d48_33%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Students learn it in a single class period.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Comments resolve themselves when the change ships.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_45deg,#1e1b4b_0_25%,#a78bfa_0_50%,#1e1b4b_0_75%,#a78bfa_0)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>The first design tool our copywriters open without being asked.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[linear-gradient(135deg,#14b8a6_0_50%,#134e4a_50%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
<ul class="flex gap-4 pr-4 motion-reduce:hidden" aria-hidden="true">
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>We run a forty-person studio on it across three time zones.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle_at_30%_30%,#c4b5fd_0_28%,transparent_29%),linear-gradient(135deg,#4338ca,#0ea5e9)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Hanne Berg</strong>Studio director</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Moodboards load instantly, even with four hundred photos.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[radial-gradient(circle,#fde68a_0_32%,#e11d48_33%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Lucas Ferreira</strong>Photographer</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Students learn it in a single class period.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Anjali Rao</strong>Design teacher</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>Comments resolve themselves when the change ships.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[conic-gradient(from_45deg,#1e1b4b_0_25%,#a78bfa_0_50%,#1e1b4b_0_75%,#a78bfa_0)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Erik Johansson</strong>UX lead</span></figcaption></figure></li>
<li class="flex w-[300px]"><figure class="flex flex-1 flex-col justify-between gap-3.5 rounded-2xl border border-[#ddd6fe] bg-white px-5 py-[18px]"><blockquote class="text-[.95rem] leading-[1.55] text-[#1e1b4b]"><p>The first design tool our copywriters open without being asked.</p></blockquote><figcaption class="flex items-center gap-2.5 text-[.85rem] leading-[1.3] text-[#4c4a6b]"><span class="size-[30px] flex-none rounded-full bg-[linear-gradient(135deg,#14b8a6_0_50%,#134e4a_50%_100%)]" aria-hidden="true"></span><span><strong class="block text-[#1e1b4b]">Bea Santos</strong>Creative director</span></figcaption></figure></li>
</ul>
</div>
</div>
</div>
</section></div>
<div><span class="mb-[18px] block text-[.72rem] tracking-[.12em] text-[#4c4a6b] uppercase">Container query card: the same markup, wide and narrow</span>
<div class="grid gap-5 md:grid-cols-2">
<div class="@container md:col-span-2"><figure class="grid h-full gap-4 rounded-[20px] border border-[#ddd6fe] bg-white p-[22px] text-[#1e1b4b] @[560px]:grid-cols-[170px_1fr] @[560px]:grid-rows-[1fr_auto] @[560px]:gap-x-8 @[560px]:bg-[linear-gradient(120deg,#f5f3ff,#fff_60%)] @[560px]:p-8">
<blockquote class="leading-[1.6] text-pretty @[560px]:col-start-2 @[560px]:self-end @[560px]:text-[1.3rem] @[560px]:leading-[1.45] @[560px]:font-medium"><p>We used to keep a spreadsheet of who approved which layout. Now the approval sits on the frame itself, with a name and a date, and the spreadsheet is gone.</p></blockquote>
<p class="text-[.8rem] font-semibold @[560px]:col-start-2 @[560px]:self-start text-[#5b21b6]">Studio plan · since 2023</p>
<figcaption class="row-start-1 flex items-center gap-3 @[560px]:col-start-1 @[560px]:row-[1/span_2] @[560px]:self-center @[560px]:flex-col @[560px]:items-start @[560px]:gap-3.5"><span class="size-11 flex-none rounded-[14px] bg-[conic-gradient(from_210deg,#7c3aed,#ec4899,#f59e0b,#7c3aed)] @[560px]:size-24 @[560px]:rounded-[28px]" aria-hidden="true"></span><span><span class="block font-bold">Yara Haddad</span><span class="block text-[.875rem] text-[#4c4a6b]">Head of Design, Olive & Ink</span></span></figcaption>
</figure></div>
<div class="@container"><figure class="grid h-full gap-4 rounded-[20px] border border-[#ddd6fe] bg-white p-[22px] text-[#1e1b4b] @[560px]:grid-cols-[170px_1fr] @[560px]:grid-rows-[1fr_auto] @[560px]:gap-x-8 @[560px]:bg-[linear-gradient(120deg,#f5f3ff,#fff_60%)] @[560px]:p-8">
<blockquote class="leading-[1.6] text-pretty @[560px]:col-start-2 @[560px]:self-end @[560px]:text-[1.3rem] @[560px]:leading-[1.45] @[560px]:font-medium"><p>The free plan carried us through our first year. We upgraded the day we hired a second designer.</p></blockquote>
<p class="text-[.8rem] font-semibold @[560px]:col-start-2 @[560px]:self-start text-[#5b21b6]">Team plan · since 2024</p>
<figcaption class="row-start-1 flex items-center gap-3 @[560px]:col-start-1 @[560px]:row-[1/span_2] @[560px]:self-center @[560px]:flex-col @[560px]:items-start @[560px]:gap-3.5"><span class="size-11 flex-none rounded-[14px] bg-[linear-gradient(135deg,#14b8a6_0_50%,#134e4a_50%_100%)] @[560px]:size-24 @[560px]:rounded-[28px]" aria-hidden="true"></span><span><span class="block font-bold">Felix Wagner</span><span class="block text-[.875rem] text-[#4c4a6b]">Founder, Wagner Type</span></span></figcaption>
</figure></div>
<div class="@container"><figure class="grid h-full gap-4 rounded-[20px] border border-[#ddd6fe] bg-white p-[22px] text-[#1e1b4b] @[560px]:grid-cols-[170px_1fr] @[560px]:grid-rows-[1fr_auto] @[560px]:gap-x-8 @[560px]:bg-[linear-gradient(120deg,#f5f3ff,#fff_60%)] @[560px]:p-8">
<blockquote class="leading-[1.6] text-pretty @[560px]:col-start-2 @[560px]:self-end @[560px]:text-[1.3rem] @[560px]:leading-[1.45] @[560px]:font-medium"><p>Our interns ship real work in their first week, because everything they need is on one board.</p></blockquote>
<p class="text-[.8rem] font-semibold @[560px]:col-start-2 @[560px]:self-start text-[#5b21b6]">Studio plan · since 2022</p>
<figcaption class="row-start-1 flex items-center gap-3 @[560px]:col-start-1 @[560px]:row-[1/span_2] @[560px]:self-center @[560px]:flex-col @[560px]:items-start @[560px]:gap-3.5"><span class="size-11 flex-none rounded-[14px] bg-[radial-gradient(circle_at_30%_30%,#c4b5fd_0_28%,transparent_29%),linear-gradient(135deg,#4338ca,#0ea5e9)] @[560px]:size-24 @[560px]:rounded-[28px]" aria-hidden="true"></span><span><span class="block font-bold">Maya Torres</span><span class="block text-[.875rem] text-[#4c4a6b]">Design Ops, Brightside Media</span></span></figcaption>
</figure></div>
</div></div>
CSS
@theme {
--animate-marquee: marquee 46s linear infinite;
@keyframes marquee {
to { transform: translateX(-50%); }
}
}
About this set
Two testimonial patterns that usually need JavaScript, done with modern CSS. The marquee scrolls two rows of short quotes in opposite directions with a CSS animation. Each row is printed twice, with the copy hidden from screen readers, so the loop has no seam. Hovering the rows, focusing a row with the keyboard, or turning on the Pause scrolling switch stops it, the switch working through the :has() selector. Under prefers-reduced-motion nothing moves at all: the copies disappear, the switch is hidden and each row becomes an ordinary horizontal scroller. The container query card shows the same markup three times. In a wide container it sets a large abstract avatar beside a big quote; in a narrow one it stacks the avatar and name above a smaller quote. The layout follows the width of the slot the card is placed in, not the width of the screen, so one component works in a sidebar, a two-column grid and a full-width band.
What’s included
CSS-only marquee in two directions
Pauses on hover, keyboard focus and a :has() switch
Stops completely under reduced motion and becomes scrollable
Container query card that adapts to its slot, not the viewport
No JavaScript in any of the three versions
Accessibility
The duplicate quotes in each row are aria-hidden, so screen readers hear every quote once. Moving content can be stopped with a labelled switch (role switch), by hovering, or by focusing a row, which is a named region with a 3px violet focus outline. With reduced motion requested the animation is removed entirely.
Customise it
Change --mq-speed for the scroll speed and --mq-accent, --mq-ink and --mq-line on .mq; change the 560px breakpoint in @container to move the point where the card switches layout. In Tailwind edit --animate-marquee in @theme and the @[560px]: variants.