Marquee text band

Marquee text band

subtle

Infinite 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; }
}
Marquee text band · CreativePower