Skip to content

Infinite Logo Marquee

Two-row infinite logo marquee with seamless CSS loop, edge fade, pause on hover, a pause button and a static fallback for reduced motion.

Live preview

Open in new tab

Code

An infinite logo marquee in pure CSS with a tiny vanilla JavaScript helper: two rows of customer logos glide in opposite directions, fade out at the edges and pause on hover. Use it as a "trusted by" strip under a hero, on pricing pages or anywhere you want social proof without taking much space.

How it works

The root section.lm-marquee contains a .lm-head with the heading and a .lm-toggle button, followed by two .lm-row elements. Each row wraps a .lm-track with one ul.lm-group of li.lm-logo items. A logo is an inline SVG mark plus a text name, so it scales crisply and is read out as text.

On DOMContentLoaded the script clones each .lm-group once, marks the copy aria-hidden="true" and adds .lm-animated to the root. In that state both groups sit side by side in the flex track and run the lm-scroll keyframes, which move each group left by its own width plus --lm-gap. When the first copy has scrolled out, the second one is exactly where the first started, so the loop has no seam. Every group has min-width: 100%, which prevents gaps on very wide screens. .lm-row--reverse plays the same animation backwards with its own duration, and a CSS mask fades the logos in and out at both edges.

Hovering a row sets animation-play-state: paused, and hovering a logo switches it from the neutral --lm-mono gray to its brand color. Without JavaScript nothing moves: the logos wrap into centered rows.

Customization

  • --lm-duration and --lm-duration-reverse on .lm-marquee: loop time of the first and second row; higher values scroll slower.
  • --lm-gap: space between logos and between the two copies of a group; 3.5rem on phones and 4.5rem from 768px.
  • --lm-fade: width of the edge fade, e.g. 20% for a softer vignette or 0% to turn it off.
  • --lm-mono and --lm-bg: the resting logo color and the section background; .lm-cut shapes use --lm-bg to punch holes in the marks.
  • .lm-logo--blue, .lm-logo--rose and the other modifiers set --lm-brand, the hover color of a logo.
  • Replace the SVG and name inside any .lm-logo with your own mark, or remove .lm-row--reverse to keep a single row.

Accessibility

Only the original groups are exposed to assistive technology; each ul.lm-group has an aria-label, and the clones are aria-hidden. SVG marks are decorative, so the company names are the accessible content. Because moving content that lasts longer than five seconds must be stoppable, the .lm-toggle button pauses both rows and reports its state with aria-pressed; it has a visible :focus-visible ring. With prefers-reduced-motion: reduce the script does not clone or animate anything, the toggle stays hidden and the logos are shown as a static, wrapped list.

Usage notes

Several marquees can share a page; each has its own toggle. Keep at least six logos per row so one group is wide enough for a smooth loop.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

Infinite Logo Marquee – Pure CSS logo clouds component screenshot
Infinite Logo Marquee · Pure CSS Logo Clouds

More Logo Clouds

Logo Cloud Grid – Tailwind CSS logo clouds preview

Logo Cloud Grid

Tailwind CSS logo cloud with a heading and a bordered grid of eight inline SVG client logos that reveal brand colors on hover.