Smooth, Infinite Scrolling Marquees in Vanilla JavaScript – marquee6k

Category: Animation , Javascript | March 31, 2026
AuthorSPACESODA
Last UpdateMarch 31, 2026
LicenseMIT
Views242 views
Smooth, Infinite Scrolling Marquees in Vanilla JavaScript – marquee6k

marquee6k is a lightweight vanilla JavaScript library that creates smooth, infinite, horizontal scrolling animations.

It serves as a modern, high-performance replacement for the deprecated HTML <marquee> tag or heavy jQuery content scrolling plugins.

Features

  • Lightweight: The library is only 3kb minified. No external dependencies are required.
  • RequestAnimationFrame: The animation loop uses requestAnimationFrame for smooth 60fps performance.
  • Multiple Instances: You can run dozens of marquee instances simultaneously.
  • Responsive Design: The library automatically adjusts to viewport changes.
  • Direction Control: Marquees can scroll left-to-right, right-to-left, or be rotated with CSS transforms.
  • Pause on Hover: Optional hover pause functionality.
  • Global Instance: Allows programmatic control via pause, play, refresh, and toggle methods.
  • CSS Styling: Fully styleable through CSS. The library only manages animation logic.

Use Cases

  • News Tickers: Display breaking news or live updates across the top of a webpage.
  • Product Showcases: Create horizontal product carousels for e-commerce sites.
  • Announcement Banners: Implement site-wide announcement bars that scroll important messages.
  • Stock Tickers: Build financial dashboards with live stock price feeds.

How To Use It:

1. Install marquee6k with NPM and import it into your JS project.

# NPM
$ npm install marquee6k
// CommonJS import
const marquee6k = require('marquee6k');
// ES6 module import
import marquee6k from 'marquee6k';

2. Or load the main script marquee6k.js in your document.

// Local
<script src="marquee6k.js"></script>
// CDN
<script src="https://cdn.jsdelivr.net/gh/SPACESODA/marquee6k@latest/marquee6k.min.js"></script>

3. Wrap your scrolling content in a DIV container with the .marquee6k class.

<div class="marquee6k">
  <div>
    <h1>Your scrolling content goes here</h1>
    <img src="logo.png" alt="Logo">
    <p>Mix text, images, and any HTML elements</p>
  </div>
</div>

4. Configure the scrolling behavior using the following data- attributes.

  • data-speed: Controls scroll speed (default: 0.25)
  • data-reverse: Scrolls right-to-left, “false” scrolls left-to-right
  • data-pausable: Pauses the animation when the mouse hovers over it
  • data-tap-pause: Pauses the animation on click/tap
  • data-direction: left / right / up / down
  • data-axis: x or y
  • data-scrubbing: Drag to scrub or not
  • data-scrub-momentum: Enable momentum scrolling or not
<div 
  class="marquee6k"
  data-speed="1.5" → play around here
  data-reverse="true" → default: R to L / T to B
  data-pausable="true">
  ...
</div>

5. Scan for all .marquee6k elements within your document and activates them:

// Call init() after the DOM is loaded
marquee6k.init();
// Initialize with a custom selector
marquee6k.init({
  selector: 'my-custom-marquee-class'
});

6. marquee6k handles the scroll animation, but you control the CSS styles. The library automatically adds a class (.marquee6k__copy) to the repeated content segments.

.marquee6k__copy {
  padding-right: 4rem; /* Gap between items */
  display: flex;
  align-items: center;
}

7. All available options and callbacks.

marquee6k.init({ 
  className: 'marquee6k', // base class for __copy (optional)
  speed: 0.25,
  pausable: false,
  tapPause: false,
  scrubbing: 600,
  scrubMomentum: false,
  reverse: false,
  axis: 'x', // 'x' | 'y'
  direction: 'left', // 'left' | 'right' | 'up' | 'down'
  onInit: (instance) => {},
  onUpdate: (instance) => {},
  onPause: (instance) => {},
  onPlay: (instance) => {},
  onUpdateThrottle: 200, // ms
});

8. API Methods.

// Refresh all marquee instances
// Use this when content width changes dynamically
marquee6k.refreshAll();
// Refresh a specific marquee by its index
// Index corresponds to DOM order (first marquee is 0)
marquee6k.refresh(0);
// Pause all active marquees
marquee6k.pauseAll();
// Pause a specific marquee
marquee6k.pause(2); // Pauses the third marquee
// Resume all paused marquees
marquee6k.playAll();
// Resume a specific marquee
marquee6k.play(1);
// Toggle play/pause for all marquees
marquee6k.toggleAll();
// Toggle a specific marquee
marquee6k.toggle(0);

Alternatives

  • Marquee3000: A similar vanilla JS library. It is also lightweight but has slightly different API methods.
  • jQuery.marquee: A classic jQuery plugin. It is robust but requires jQuery as a dependency.
  • Best Marquee Plugins: 10 Best Marquee-like Content Scrolling Plugins In JavaScript

FAQs:

Q: Why does my marquee stutter on mobile devices?
A: Stuttering usually happens when the browser is forced to recalculate layouts during animation. Make sure you’re applying will-change: transform to the .marquee6k element in your CSS. This hints to the browser to prepare for transforms.

Q: Can I use marquee6k with a fixed position container?
A: Yes, but you need to wrap the marquee element in a fixed position container rather than applying fixed positioning directly to the .marquee6k element. The library needs its parent to have a measurable width for proper initialization.

Q: How do I prevent content from clipping at the edges?
A: The marquee container needs overflow: hidden applied to its parent. If you see clipping issues, check that the parent container has defined dimensions. You can also add overflow: hidden directly to a wrapper around the .marquee6k element.

Q: Why doesn’t the pause method work immediately?
A: The pause method sets a flag that’s checked in the next animation frame. There’s a single-frame delay between calling marquee6k.pause(index) and the animation actually stopping. This is normal behavior for requestAnimationFrame-based animations.

Changelog:

v1.3.8 (03/31/2026)

  • Improves resize behavior by using a safer full reflow path to keep marquee clones in sync with layout changes, while preserving backward compatibility for existing repopulate(…) callers.

v1.3.7 (01/25/2026)

  • Improve mobile scrubbing smoothness and responsiveness

v1.3.6 (01/22/2026)

  • Update

v1.3.5 (01/22/2026)

  • Added direction/axis support (left/right/up/down + x/y) with init defaults; per‑element data-* still overrides.
  • New callbacks (onInit, onUpdate, onPause, onPlay) plus onUpdateThrottle.
  • Selector handling improved: full CSS selectors supported and new className option for safe __copy classes.
  • Refresh now fully reflows clones; re‑init is safer (no nested wrappers or duplicate listeners).

You Might Be Interested In:


Leave a Reply