002

Infinite Marquee with Mouse Control

£7
or the whole Vault, £99

Continuous scrolling marquees with mouse-based speed control. Rewind, pause, or fast-forward with cursor position. Uses GSAP quickTo for 60fps.

ScrollTrigger intermediate
4 more details
marqueequickTowrapviewport-aware-ticker

Updated

About this effect

A stack of marquee bands a real site would ship (a partner strip, two display-type bands, a filled call-to-action band and a row of photographs) that turns pointer position into playback control. Speed eases as visitors move from rewind on the left, through a centre hold, to full speed on the right, while each band keeps its own direction and pace.

Infinite Marquee with Mouse Control - GSAP animation effect preview

What's included

9 items
  • Continuous infinite loop with no visible seam or reset jump
  • Mouse-position speed control: rewind, pause, and fast-forward
  • GSAP quickTo for 60fps interpolated speed transitions
  • Viewport-aware ticker that pauses when off-screen to save resources
  • Multiple marquee rows with independent speeds and directions
  • Shared control surface for coordinated multi-row compositions
  • Responsive design that adapts to any screen width
  • Tap-to-pause and keyboard controls
  • GSAP context cleanup for SPA compatibility

Perfect for

5 use cases
  • Client logos and partner brand strips
  • Testimonial and review tickers
  • News headlines and announcement bars
  • Portfolio project showcases
  • Award and recognition displays

How it works

1 section

Each row loops continuously with no visible seam or jump at the wrap point, and the pointer's horizontal position sets playback: left of centre rewinds, the middle holds, and the right runs forward, with every change in speed eased in. Rows only animate while they are on screen. Touch and keyboard controls can pause individual rows.

Plugins ScrollTrigger
Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

The Vault opens this source and the whole library.

Each product gives you the HTML, CSS and JavaScript source, the full documentation and an AI setup prompt, licensed for unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

One payment, over 300 products, and future additions to the library.

Documentation

Quick Start

1. Add to your HTML <head>:

In your downloadThe working code for this step, in index.html.

2. Add a control surface and marquee to your <body>:

In your downloadThe working code for this step, in index.html.

The script clones .marquee-inner; do not manually duplicate the row.

3. Add before the closing </body> tag:

In your downloadThe working code for this step, in index.html.

Using It With Your Own Design

What the script needs from your markup. One control surface (.showcase-stage, or the document body if there is none) and, inside it, any number of .marquee elements each wrapping exactly one .marquee-inner. That is the whole contract: the script wraps the inner in a generated .marquee-track, clones it once, measures the inner's width and loops it. Everything inside .marquee-inner is yours: text, logos, <figure> tiles with images, links.

Make the content wider than the band. The loop is one inner plus one clone, so .marquee-inner must be at least as wide as the .marquee it sits in or a gap shows at the seam. Repeat your items until it is (the demo repeats each phrase three times).

Structural CSS the loop depends on. These three rules are the effect; keep them whatever else you change:

In your downloadThe working code for this step, in style.css.

Demo-only CSS you can delete. .marquee--clients, .marquee--display, .marquee--outline, .marquee--accent, .marquee--tiles, .marquee-client, .marquee-item, .marquee-mark, .marquee-tile, the toolbar and the .speed-readout are the included showcase, not the effect. The band heights come from the grid-template-rows on .showcase-stage; drop that and each band takes the height of its content.

Fonts and measurement. The script waits for document.fonts.ready before it measures, and re-measures through a ResizeObserver whenever a row's content changes width (a viewport resize, a late image). If you load a webfont, load it before the script or let the observer catch the swap; either way the seam stays closed.

Optional hooks. An element with data-marquee-readout anywhere in the document receives the live speed as text (1.0×, −2.4×, Hold). The control surface also carries a --energy custom property from 0 to 1 (how far the speed is from resting), which the demo no longer styles but is there for a glow, a scale or anything else you want driven by pace.

Photographs. The tile band's images live in assets/img/ and are baked from assets/img-manifest.json. Replace the <img> sources with your own; the .marquee-tile plate sets the size, so any aspect ratio crops to it with object-fit: cover.

Options

Attribute Values Default Description
data-direction left, right left Resting direction for the row
data-speed Positive number 1 Base speed multiplier for the row

All marquees inside .showcase-stage share one pointer control surface. Moving over the left 40% rewinds, the middle 20% holds, and the right 40% accelerates. If no .showcase-stage exists, the document body becomes the control surface.

Multiple Rows

Give each row a different direction and base speed to create counter-motion:

In your downloadThe working code for this step, in index.html.

Styling

The demo stacks five bands on a grey ground in Mona Sans: a partner strip, a headline band in ink, a dates band in outline, a filled accent band and a row of photographs. Customise .marquee-item, .marquee-mark and the custom properties in :root (--page, --ink, --accent, --display-size, --band-size, --tile-height) to match your project. Text on the accent band uses --accent-ink; keep it dark on a bright accent so it clears 4.5:1.

Accessibility

  • Reduced motion leaves every row visible and stationary.
  • Cloned tracks receive aria-hidden="true".
  • Touch users can tap a row to pause it.
  • Keyboard users can focus a row and press Enter or Space to pause or resume it.
  • Keep a descriptive aria-label on each interactive marquee.

Dependencies

  • GSAP 3.15.0+
  • ScrollTrigger

Also in your download: the full source, worked examples, the events and programmatic API, and the class reference.

£7