marqueeMarquee
跑马灯Text or content that scrolls continuously in a loop.
文字或内容持续循环滚动。
Continuously scroll overflowing content and pause it on hover or focus.
Text or content that scrolls continuously in a loop.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
marqueeText or content that scrolls continuously in a loop.
文字或内容持续循环滚动。
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Present an overlong information stream in limited space while allowing users to pause and read.
Use sparingly for brands, partners, or live status strips while keeping core text statically accessible.
Run only when content overflows and playback is active, remaining still when content fits.
Join duplicated content into a seamless track and stop at a fully readable position.
Pause at the current position on hover, focus, or page hide, and continue on resume.
Let users pause through hover, focus, and a control while keeping one keyboard-accessible copy of track content.
Stop scrolling and wrap content or provide a statically browsable horizontal list.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.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; }
}Stop scrolling and wrap content or provide a statically browsable horizontal list.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 2000ms–20000ms | 8000ms | Controls the rhythm of one full cycle; continuous motion should stay pausable and low-distraction. |
gap | 8px–80px | 32px | Adjusts content gap. |
direction | Left / Right | Left | Selects direction. |
pauseOnHover | On / Off | On | Pauses motion on hover or focus. |