Marquee text band
subtleInfinite scrolling text band, pure CSS.
Horizontally scrolling text band with no JS required — uses CSS @keyframes. Duplicate the item set so the loop is seamless. Great as a value-prop section between hero and features, or as a footer brand reinforcement.
animatedtexttickerinfinitecss-only
━━ Use this pattern
━━ Live preview
━━ HTML markup
<div class="mq-track" aria-label="Brand values">
<div class="mq-inner">
<span class="mq-item">Token <span class="accent">first</span><span class="dot">·</span></span>
<span class="mq-item">Brand <span class="accent">coherent</span><span class="dot">·</span></span>
<span class="mq-item">Ship <span class="accent">fast</span><span class="dot">·</span></span>
<span class="mq-item">Design <span class="accent">systems</span><span class="dot">·</span></span>
<!-- Duplicate set so the scroll loop is seamless -->
<span class="mq-item">Token <span class="accent">first</span><span class="dot">·</span></span>
<span class="mq-item">Brand <span class="accent">coherent</span><span class="dot">·</span></span>
<span class="mq-item">Ship <span class="accent">fast</span><span class="dot">·</span></span>
<span class="mq-item">Design <span class="accent">systems</span><span class="dot">·</span></span>
</div>
</div>━━ CSS
.mq-track {
display: flex;
gap: 4rem;
overflow: hidden;
white-space: nowrap;
padding: 2.5rem 0;
/* stageMode "adaptive": rules and type only. */
--mq-line: color-mix(in oklab, var(--color-surface, #1a1c20) 88%, var(--color-on-surface, #1a1c20));
--mq-ink: var(--color-on-surface, #fafafa);
--mq-ink-mute: color-mix(in oklab, var(--color-on-surface, #6b7280) 45%, var(--color-surface, #6b7280));
/* The italic word mixes toward the surface first, so a dark or cool primary still
reads as the accent beat rather than as a gap in the band. */
--mq-accent: color-mix(in oklab, var(--color-primary, #ff6b1a) 80%, var(--color-surface, #ff6b1a));
border-top: 1px solid var(--mq-line);
border-bottom: 1px solid var(--mq-line);
}
.mq-inner {
display: inline-flex;
gap: 4rem;
animation: mq-scroll 30s linear infinite;
}
.mq-item {
font-family: "Geist", system-ui, sans-serif;
font-size: clamp(2rem, 6vw, 4rem);
font-weight: 700;
letter-spacing: -0.03em;
color: var(--mq-ink);
flex-shrink: 0;
}
.mq-item .accent {
font-family: "Instrument Serif", serif;
font-style: italic;
font-weight: 400;
color: var(--mq-accent);
}
.mq-item .dot { color: var(--mq-ink-mute); margin: 0 0.5em; }
@keyframes mq-scroll {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
.mq-inner { animation: none; }
}