fluid-marquee

A lightweight, zero-dependency marquee/scrolling content library using modern JavaScript and CSS.

Just add the fluid-marquee class to any container.

Features

  • No dependencies
  • Only scrolls when content actually overflows
  • Horizontal or vertical
  • Configurable speed, in either direction
  • Smooth ease in/out on pause and resume
  • Pause on hover, on click, or both
  • Drag-to-scrub with momentum, on mouse and touch
  • Auto recalculates on resize and when images finish loading
  • Auto pauses when scrolled off-screen
  • Programmatic API for pause, resume, and item management

Basic Usage

Wrap your items in a fluid-marquee container and tag each item with fluid-marquee-item:

Free shipping over $50
New arrivals every week
Sign up for 10% off
30-day returns
Customer support 24/7
<div class="fluid-marquee" data-fluid-marquee-infinite>
  <div class="fluid-marquee-item">Free shipping over $50</div>
  <div class="fluid-marquee-item">New arrivals every week</div>
  <div class="fluid-marquee-item">Sign up for 10% off</div>
</div>

Only scrolls when needed

Without data-fluid-marquee-infinite, the marquee only animates when the contents overflow the container. If they fit, items stay static and centered:

First
Second
Third
Fourth

Squish your browser narrower until the four items no longer fit, and the marquee automatically starts scrolling. Widen it again and it stops and re-centers.

<div class="fluid-marquee">
  <div class="fluid-marquee-item">First</div>
  <div class="fluid-marquee-item">Second</div>
  <div class="fluid-marquee-item">Third</div>
</div>

All examples below use data-fluid-marquee-infinite so they always scroll regardless of viewport width. The snippets omit it for clarity.

Speed and direction

Set scroll speed in pixels per second with data-fluid-marquee-speed. Negative values scroll in reverse:

Slow
And
Steady
Wins
The race
Fast
Faster
Fastest
Zoom
Zoom
Reverse one
Reverse two
Reverse three
Reverse four
Reverse five
<div class="fluid-marquee" data-fluid-marquee-speed="32">…</div>
<div class="fluid-marquee" data-fluid-marquee-speed="200">…</div>
<div class="fluid-marquee" data-fluid-marquee-speed="-96">…</div>

Pause on hover, click, or both

Add data-fluid-marquee-pausable for both behaviors, or pick a single one with data-fluid-marquee-pause-hover or data-fluid-marquee-pause-click. Hover auto resumes on mouse leave. Click locks pause until you click anywhere outside the marquee:

Hover or click to pause
Smooth ease-in
Smooth ease-out
Click outside to resume
Hover-only auto resumes
<div class="fluid-marquee" data-fluid-marquee-pausable>…</div>
<div class="fluid-marquee" data-fluid-marquee-pause-hover>…</div>
<div class="fluid-marquee" data-fluid-marquee-pause-click>…</div>

Drag to scrub

Add data-fluid-marquee-draggable to let users grab and scrub through the marquee. Flicking on release applies momentum that decays smoothly back into the normal scroll. On touch, only the marquee's axis is captured, so page scrolling still works:

Drag me
Flick to throw
Momentum decays
Back to normal
Works on touch
<div class="fluid-marquee" data-fluid-marquee-draggable>…</div>

Vertical

Add data-fluid-marquee-vertical and give the container a height:

First
Second
Third
Fourth
Fifth
Sixth
<div class="fluid-marquee"
     data-fluid-marquee-vertical
     data-fluid-marquee-draggable
     style="height: 280px;">
  …
</div>

Images

The marquee automatically re-measures after images finish loading, so you don't need to wait for them yourself:

Programmatic API

Get the instance via el.marquee (or FluidMarquee.get(el)) and drive it from JavaScript. Add and remove items, pause and resume, query current state:

Item 1
Item 2
Item 3
const el = document.querySelector(".fluid-marquee")
const m = FluidMarquee.init(el)

// Pause / resume
m.pause()
m.resume()

// Item management
m.add(itemEl)
m.remove(itemEl)
m.setItems([a, b, c])
m.items                  // current items

// State
m.paused, m.apiPaused, m.userPaused
m.hoverPaused, m.clickPaused, m.dragPaused