Marquee

Continuously scroll overflowing content and pause it on hover or focus.

Preview

Live preview

Text or content that scrolls continuously in a loop.

Preview
MarqueeMotionInterface
Authoritative vocabulary

Definition and close-term distinctions

English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.

Canonical termmarquee

Marquee

跑马灯
Authoritative definition

Text or content that scrolls continuously in a loop.

Chinese translation

文字或内容持续循环滚动。

Browse all 91 terms
Design contract

Decide before this motion ships

Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.

Purpose

Present an overlong information stream in limited space while allowing users to pause and read.

Frequency

Use sparingly for brands, partners, or live status strips while keeping core text statically accessible.

Trigger

Run only when content overflows and playback is active, remaining still when content fits.

Enter / exit

Join duplicated content into a seamless track and stop at a fully readable position.

Interruptibility

Pause at the current position on hover, focus, or page hide, and continue on resume.

Gesture and keyboard

Let users pause through hover, focus, and a control while keeping one keyboard-accessible copy of track content.

Reduced-motion strategy

Stop scrolling and wrap content or provide a statically browsable horizontal list.

Output

Copy into your interface

Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.

Updates with parameters
motion.css
.motion-demo.motion-demo--marquee {
  position: relative;
  display: grid;
  place-items: center;
  width: min(100%, 34rem);
  min-height: 15rem;
  padding: 2rem;
  overflow: hidden;
  color: #18181b;
  background: #fafafa;
  border: 1px solid #e4e4e7;
  border-radius: 12px;
  isolation: isolate;
}

.motion-demo.motion-demo--marquee *, .motion-demo.motion-demo--marquee *::before, .motion-demo.motion-demo--marquee *::after {
  box-sizing: border-box;
}

.motion-demo.motion-demo--marquee .motion-surface {
  position: relative;
  display: grid;
  gap: 0.65rem;
  width: min(100%, 18rem);
  padding: 1.25rem;
  background: #ffffff;
  border: 1px solid #e4e4e7;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 10px 28px rgb(0 0 0 / 7%);
}

.motion-demo.motion-demo--marquee .motion-line {
  display: block;
  width: 100%;
  height: 0.5rem;
  background: #e4e4e7;
  border-radius: 999px;
}

.motion-demo.motion-demo--marquee .motion-line:last-child { width: 62%; }

.motion-demo.motion-demo--marquee .motion-button {
  position: relative;
  min-height: 2.75rem;
  padding: 0.75rem 1.1rem;
  color: white;
  font: inherit;
  font-weight: 700;
  background: #18181b;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--marquee .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }

.motion-demo.motion-demo--marquee .motion-action-row {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.motion-demo.motion-demo--marquee .motion-replay-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--marquee .motion-pausable-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--marquee button.motion-surface {
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.motion-demo.motion-demo--marquee .motion-replay-button,
.motion-demo.motion-demo--marquee .motion-undo-button,
.motion-demo.motion-demo--marquee .motion-dismiss-button,
.motion-demo.motion-demo--marquee .motion-pause-button {
  min-height: 2.75rem;
  padding: 0.65rem 0.9rem;
  color: #18181b;
  font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
  background: #ffffff;
  border: 1px solid #d4d4d8;
  border-radius: 7px;
  cursor: pointer;
}

.motion-demo.motion-demo--marquee .motion-replay-button:focus-visible,
.motion-demo.motion-demo--marquee .motion-undo-button:focus-visible,
.motion-demo.motion-demo--marquee .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--marquee .motion-pause-button:focus-visible,
.motion-demo.motion-demo--marquee [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--marquee [data-swipe-target]:focus-visible {
  outline: 3px solid rgb(37 99 235 / 32%);
  outline-offset: 3px;
}

.motion-demo.motion-demo--marquee .motion-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.motion-demo.motion-demo--marquee .motion-ripple-ink {
  position: absolute;
  width: 12px;
  height: 12px;
  pointer-events: none;
  background: rgb(255 255 255 / 72%);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.95);
  opacity: 0;
}

.motion-demo.motion-demo--marquee .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--marquee .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--marquee .motion-state--to { background: #18181b; color: white; }

.motion-demo.motion-demo--marquee .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--marquee .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--marquee .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--marquee svg { width: min(100%, 20rem); height: auto; }

.motion-demo.motion-demo--marquee .motion-marquee { display: flex; width: 100%; overflow: hidden; }
.motion-demo.motion-demo--marquee .motion-marquee-track { display: flex; flex: none; gap: 32px; min-width: max-content; animation: motion-marquee 8000ms linear infinite normal; }
.motion-demo.motion-demo--marquee .motion-marquee-item { padding: 0.75rem 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 999px; }
.motion-demo.motion-demo--marquee .motion-marquee:focus-within .motion-marquee-track { animation-play-state: paused; }
@media (hover: hover) and (pointer: fine) { .motion-demo.motion-demo--marquee .motion-marquee:hover .motion-marquee-track { animation-play-state: paused; } }
@keyframes motion-marquee { to { transform: translateX(calc(-50% - 16px)); } }

@keyframes motion-marquee-reduced-fade {
  from { opacity: 0.84; }
  to { opacity: 1; }
}

.force-reduced-motion .motion-demo.motion-demo--marquee {
  animation: motion-marquee-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}

.force-reduced-motion .motion-demo.motion-demo--marquee *,
.force-reduced-motion .motion-demo.motion-demo--marquee *::before,
.force-reduced-motion .motion-demo.motion-demo--marquee *::after {
  animation: none !important;
  animation-delay: 0ms !important;
  animation-iteration-count: 1 !important;
  transition-property: opacity, color, background-color, border-color !important;
  transition-duration: 160ms !important;
  transition-delay: 0ms !important;
  scroll-behavior: auto !important;
}

.force-reduced-motion .motion-demo.motion-demo--marquee .motion-button,
.force-reduced-motion .motion-demo.motion-demo--marquee [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--marquee [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--marquee [data-spring-target] {
  transform: none !important;
}

.force-reduced-motion .motion-demo.motion-demo--marquee .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--marquee .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--marquee .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .motion-demo.motion-demo--marquee {
    animation: motion-marquee-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
  }

  .motion-demo.motion-demo--marquee *, .motion-demo.motion-demo--marquee *::before, .motion-demo.motion-demo--marquee *::after {
    animation: none !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-property: opacity, color, background-color, border-color !important;
    transition-duration: 160ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  .motion-demo.motion-demo--marquee .motion-button,
  .motion-demo.motion-demo--marquee [data-reorder-item],
  .motion-demo.motion-demo--marquee [data-swipe-target],
  .motion-demo.motion-demo--marquee [data-spring-target] {
    transform: none !important;
  }

  .motion-demo.motion-demo--marquee .motion-path { stroke-dashoffset: 0 !important; }
  .motion-demo.motion-demo--marquee .motion-word--from { opacity: 0 !important; visibility: hidden; }
  .motion-demo.motion-demo--marquee .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}
Review notes

Pre-delivery review

  • Hide duplicate copies from screen readers.
  • Calibrate speed against text length and reading time.
Accessibility

Keep information accessible

Reduced motion

Stop scrolling and wrap content or provide a statically browsable horizontal list.

Parameters

Parameter reference

ParameterRange / optionsDefaultPurpose
duration2000ms–20000ms8000msControls the rhythm of one full cycle; continuous motion should stay pausable and low-distraction.
gap8px–80px32pxAdjusts content gap.
directionLeft / RightLeftSelects direction.
pauseOnHoverOn / OffOnPauses motion on hover or focus.