12 CSS Infinite Marquee Designs09 / 12

Pure CSSMIT licensed

Image-Heavy Brand Wall — Multi-Row Masonry Marquee Background

A full-bleed, three-row wall of mixed-width imagery drifting at three different speeds and directions — the 'living moodboard' agencies and creator brands run behind hero copy. Rows use varied tile widths and subtle tilts so it reads masonry, a dark scrim keeps foreground text at AAA contrast, and the whole wall is aria-hidden because it is decoration by design.

Published

Live Demo
Try it

The code

<section class="mqs-09" aria-label="Image brand wall marquee demo">
  <div class="mqs-09__wall" aria-hidden="true">
    <div class="mqs-09__viewport">
      <div class="mqs-09__group" style="--speed:48s">
        <span class="mqs-09__tile" style="width:220px;--g:linear-gradient(135deg,#f472b6,#c026d3)"></span>
        <span class="mqs-09__tile" style="width:150px;--g:linear-gradient(135deg,#38bdf8,#1d4ed8)"></span>
        <span class="mqs-09__tile" style="width:260px;--g:linear-gradient(135deg,#fbbf24,#ea580c)"></span>
        <span class="mqs-09__tile" style="width:170px;--g:linear-gradient(135deg,#34d399,#0f766e)"></span>
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#a78bfa,#6d28d9)"></span>
      </div>
      <div class="mqs-09__group" style="--speed:48s">
        <span class="mqs-09__tile" style="width:220px;--g:linear-gradient(135deg,#f472b6,#c026d3)"></span>
        <span class="mqs-09__tile" style="width:150px;--g:linear-gradient(135deg,#38bdf8,#1d4ed8)"></span>
        <span class="mqs-09__tile" style="width:260px;--g:linear-gradient(135deg,#fbbf24,#ea580c)"></span>
        <span class="mqs-09__tile" style="width:170px;--g:linear-gradient(135deg,#34d399,#0f766e)"></span>
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#a78bfa,#6d28d9)"></span>
      </div>
    </div>
    <div class="mqs-09__viewport">
      <div class="mqs-09__group mqs-09__group--rev" style="--speed:62s">
        <span class="mqs-09__tile" style="width:180px;--g:linear-gradient(135deg,#fb7185,#be123c)"></span>
        <span class="mqs-09__tile" style="width:240px;--g:linear-gradient(135deg,#4ade80,#15803d)"></span>
        <span class="mqs-09__tile" style="width:140px;--g:linear-gradient(135deg,#facc15,#a16207)"></span>
        <span class="mqs-09__tile" style="width:210px;--g:linear-gradient(135deg,#22d3ee,#0e7490)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#c084fc,#7e22ce)"></span>
      </div>
      <div class="mqs-09__group mqs-09__group--rev" style="--speed:62s">
        <span class="mqs-09__tile" style="width:180px;--g:linear-gradient(135deg,#fb7185,#be123c)"></span>
        <span class="mqs-09__tile" style="width:240px;--g:linear-gradient(135deg,#4ade80,#15803d)"></span>
        <span class="mqs-09__tile" style="width:140px;--g:linear-gradient(135deg,#facc15,#a16207)"></span>
        <span class="mqs-09__tile" style="width:210px;--g:linear-gradient(135deg,#22d3ee,#0e7490)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#c084fc,#7e22ce)"></span>
      </div>
    </div>
    <div class="mqs-09__viewport">
      <div class="mqs-09__group" style="--speed:55s">
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#818cf8,#3730a3)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#f97316,#9a3412)"></span>
        <span class="mqs-09__tile" style="width:250px;--g:linear-gradient(135deg,#2dd4bf,#115e59)"></span>
        <span class="mqs-09__tile" style="width:145px;--g:linear-gradient(135deg,#e879f9,#a21caf)"></span>
        <span class="mqs-09__tile" style="width:190px;--g:linear-gradient(135deg,#94a3b8,#334155)"></span>
      </div>
      <div class="mqs-09__group" style="--speed:55s">
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#818cf8,#3730a3)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#f97316,#9a3412)"></span>
        <span class="mqs-09__tile" style="width:250px;--g:linear-gradient(135deg,#2dd4bf,#115e59)"></span>
        <span class="mqs-09__tile" style="width:145px;--g:linear-gradient(135deg,#e879f9,#a21caf)"></span>
        <span class="mqs-09__tile" style="width:190px;--g:linear-gradient(135deg,#94a3b8,#334155)"></span>
      </div>
    </div>
  </div>
  <div class="mqs-09__fore">
    <h3 class="mqs-09__hero">Made with the brands you love</h3>
    <p class="mqs-09__sub">Swap the gradient tiles for campaign imagery — the wall is pure decoration, invisible to screen readers.</p>
  </div>
</section>
.mqs-09,
.mqs-09 *,
.mqs-09 *::before,
.mqs-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.mqs-09 {
  width: 100%;
  --gap: 18px;
  position: relative;
  font-family: 'Segoe UI',system-ui,sans-serif;
  background: #09090b;
  overflow: hidden;
  min-height: 100vh;
  display: grid;
}

.mqs-09__wall {
  position: absolute;
  inset: -30px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--gap);
}

.mqs-09__viewport {
  display: flex;
  gap: var(--gap);
  overflow: hidden;
}

.mqs-09__group {
  flex: none;
  display: flex;
  gap: var(--gap);
  animation: mqs-09-scroll var(--speed) linear infinite;
  will-change: transform;
}

.mqs-09__group--rev {
  animation-direction: reverse;
}

@keyframes mqs-09-scroll {
  to {
    transform: translateX(calc(-100% - var(--gap)));
  }
}

.mqs-09__tile {
  flex: none;
  aspect-ratio: 3/2;
  border-radius: 14px;
  background: var(--g);
  opacity: .8;
}

.mqs-09__tile:nth-child(odd) {
  rotate: 1.2deg;
}

.mqs-09__tile:nth-child(even) {
  rotate: -1.2deg;
}

.mqs-09__fore {
  position: relative;
  z-index: 1;
  display: grid;
  place-content: center;
  gap: 12px;
  text-align: center;
  padding: 64px 24px;
  background: radial-gradient(ellipse 70% 80% at 50% 50%,rgba(9,9,11,.92) 30%,rgba(9,9,11,.55) 70%,rgba(9,9,11,.25));
}

.mqs-09__hero {
  font-size: clamp(26px,5vw,44px);
  font-weight: 800;
  color: #fafafa;
  letter-spacing: -.03em;
  text-wrap: balance;
}

.mqs-09__sub {
  font-size: 14px;
  color: #a1a1aa;
  max-width: 52ch;
  margin-inline: auto;
  text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
  .mqs-09__group {
    animation: none;
  }
}
/* No JavaScript — three counter-phased rows (--speed + animation-direction each) create the faux-parallax depth; the wall is aria-hidden decoration behind a scrim. */
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Infinite Marquee Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Image-Heavy Brand Wall — Multi-Row Masonry Marquee Background
Source: https://codefronts.com/motion/css-infinite-marquee/image-brand-wall-multi-row-marquee/

A full-bleed, three-row wall of mixed-width imagery drifting at three different speeds and directions — the 'living moodboard' agencies and creator brands run behind hero copy. Rows use varied tile widths and subtle tilts so it reads masonry, a dark scrim keeps foreground text at AAA contrast, and the whole wall is aria-hidden because it is decoration by design.
## HTML
```html
<section class="mqs-09" aria-label="Image brand wall marquee demo">
  <div class="mqs-09__wall" aria-hidden="true">
    <div class="mqs-09__viewport">
      <div class="mqs-09__group" style="--speed:48s">
        <span class="mqs-09__tile" style="width:220px;--g:linear-gradient(135deg,#f472b6,#c026d3)"></span>
        <span class="mqs-09__tile" style="width:150px;--g:linear-gradient(135deg,#38bdf8,#1d4ed8)"></span>
        <span class="mqs-09__tile" style="width:260px;--g:linear-gradient(135deg,#fbbf24,#ea580c)"></span>
        <span class="mqs-09__tile" style="width:170px;--g:linear-gradient(135deg,#34d399,#0f766e)"></span>
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#a78bfa,#6d28d9)"></span>
      </div>
      <div class="mqs-09__group" style="--speed:48s">
        <span class="mqs-09__tile" style="width:220px;--g:linear-gradient(135deg,#f472b6,#c026d3)"></span>
        <span class="mqs-09__tile" style="width:150px;--g:linear-gradient(135deg,#38bdf8,#1d4ed8)"></span>
        <span class="mqs-09__tile" style="width:260px;--g:linear-gradient(135deg,#fbbf24,#ea580c)"></span>
        <span class="mqs-09__tile" style="width:170px;--g:linear-gradient(135deg,#34d399,#0f766e)"></span>
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#a78bfa,#6d28d9)"></span>
      </div>
    </div>
    <div class="mqs-09__viewport">
      <div class="mqs-09__group mqs-09__group--rev" style="--speed:62s">
        <span class="mqs-09__tile" style="width:180px;--g:linear-gradient(135deg,#fb7185,#be123c)"></span>
        <span class="mqs-09__tile" style="width:240px;--g:linear-gradient(135deg,#4ade80,#15803d)"></span>
        <span class="mqs-09__tile" style="width:140px;--g:linear-gradient(135deg,#facc15,#a16207)"></span>
        <span class="mqs-09__tile" style="width:210px;--g:linear-gradient(135deg,#22d3ee,#0e7490)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#c084fc,#7e22ce)"></span>
      </div>
      <div class="mqs-09__group mqs-09__group--rev" style="--speed:62s">
        <span class="mqs-09__tile" style="width:180px;--g:linear-gradient(135deg,#fb7185,#be123c)"></span>
        <span class="mqs-09__tile" style="width:240px;--g:linear-gradient(135deg,#4ade80,#15803d)"></span>
        <span class="mqs-09__tile" style="width:140px;--g:linear-gradient(135deg,#facc15,#a16207)"></span>
        <span class="mqs-09__tile" style="width:210px;--g:linear-gradient(135deg,#22d3ee,#0e7490)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#c084fc,#7e22ce)"></span>
      </div>
    </div>
    <div class="mqs-09__viewport">
      <div class="mqs-09__group" style="--speed:55s">
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#818cf8,#3730a3)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#f97316,#9a3412)"></span>
        <span class="mqs-09__tile" style="width:250px;--g:linear-gradient(135deg,#2dd4bf,#115e59)"></span>
        <span class="mqs-09__tile" style="width:145px;--g:linear-gradient(135deg,#e879f9,#a21caf)"></span>
        <span class="mqs-09__tile" style="width:190px;--g:linear-gradient(135deg,#94a3b8,#334155)"></span>
      </div>
      <div class="mqs-09__group" style="--speed:55s">
        <span class="mqs-09__tile" style="width:200px;--g:linear-gradient(135deg,#818cf8,#3730a3)"></span>
        <span class="mqs-09__tile" style="width:160px;--g:linear-gradient(135deg,#f97316,#9a3412)"></span>
        <span class="mqs-09__tile" style="width:250px;--g:linear-gradient(135deg,#2dd4bf,#115e59)"></span>
        <span class="mqs-09__tile" style="width:145px;--g:linear-gradient(135deg,#e879f9,#a21caf)"></span>
        <span class="mqs-09__tile" style="width:190px;--g:linear-gradient(135deg,#94a3b8,#334155)"></span>
      </div>
    </div>
  </div>
  <div class="mqs-09__fore">
    <h3 class="mqs-09__hero">Made with the brands you love</h3>
    <p class="mqs-09__sub">Swap the gradient tiles for campaign imagery — the wall is pure decoration, invisible to screen readers.</p>
  </div>
</section>
```
## CSS
```css
.mqs-09,
.mqs-09 *,
.mqs-09 *::before,
.mqs-09 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.mqs-09 {
  width: 100%;
  --gap: 18px;
  position: relative;
  font-family: 'Segoe UI',system-ui,sans-serif;
  background: #09090b;
  overflow: hidden;
  min-height: 100vh;
  display: grid;
}

.mqs-09__wall {
  position: absolute;
  inset: -30px 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--gap);
}

.mqs-09__viewport {
  display: flex;
  gap: var(--gap);
  overflow: hidden;
}

.mqs-09__group {
  flex: none;
  display: flex;
  gap: var(--gap);
  animation: mqs-09-scroll var(--speed) linear infinite;
  will-change: transform;
}

.mqs-09__group--rev {
  animation-direction: reverse;
}

@keyframes mqs-09-scroll {
  to {
    transform: translateX(calc(-100% - var(--gap)));
  }
}

.mqs-09__tile {
  flex: none;
  aspect-ratio: 3/2;
  border-radius: 14px;
  background: var(--g);
  opacity: .8;
}

.mqs-09__tile:nth-child(odd) {
  rotate: 1.2deg;
}

.mqs-09__tile:nth-child(even) {
  rotate: -1.2deg;
}

.mqs-09__fore {
  position: relative;
  z-index: 1;
  display: grid;
  place-content: center;
  gap: 12px;
  text-align: center;
  padding: 64px 24px;
  background: radial-gradient(ellipse 70% 80% at 50% 50%,rgba(9,9,11,.92) 30%,rgba(9,9,11,.55) 70%,rgba(9,9,11,.25));
}

.mqs-09__hero {
  font-size: clamp(26px,5vw,44px);
  font-weight: 800;
  color: #fafafa;
  letter-spacing: -.03em;
  text-wrap: balance;
}

.mqs-09__sub {
  font-size: 14px;
  color: #a1a1aa;
  max-width: 52ch;
  margin-inline: auto;
  text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
  .mqs-09__group {
    animation: none;
  }
}
```

## JavaScript
```js
/* No JavaScript — three counter-phased rows (--speed + animation-direction each) create the faux-parallax depth; the wall is aria-hidden decoration behind a scrim. */
```

How this works

Three stacked marquee rows, each with its own --speed and alternating animation-direction, create parallax-like depth: the eye reads different speeds as different distances. Tiles are aspect-ratio-driven boxes of varied widths (140–260px) so each row has a broken, masonry-ish rhythm rather than a grid march; alternate tiles carry a ±1.2deg rotation for a hand-placed feel.

This demo ships with gradient placeholder tiles — swap each tile's background for <img loading="lazy" alt=""> or a CSS background-image. Because tiles declare aspect-ratio + explicit width, the track width is stable BEFORE any image loads: zero CLS and no loop desync while images stream in.

The whole wall is aria-hidden="true" and sits behind a foreground layer with a scrim gradient — the correct architecture when a marquee is ambience: screen readers skip it entirely, the hero copy on top stays ≥7:1 contrast, and prefers-reduced-motion simply freezes the wall into a static collage (nothing scrolls, nothing is lost, the vibe survives).

Techniques used: three counter-phased rows (--speed + animation-direction per row) for faux parallax · aspect-ratio + fixed widths for CLS-free image slots · alternating micro-rotations for masonry feel · aria-hidden decorative layer + scrim overlay for text contrast · reduced-motion freeze (static collage, not removal)

Make it yours

  • Swap tiles for real images: <img src loading="lazy" alt="" class="mqs-09__img"> inside each tile — keep alt empty, the wall is decorative.
  • Depth illusion: keep row speeds ~25% apart (48s / 62s / 55s here); equal speeds flatten it instantly.
  • Tilt amount: the ±1.2deg on nth-child rules — 0 for corporate, up to 3deg for scrapbook.
  • Scrim strength: the rgba stops in the overlay gradient; check your headline still hits 4.5:1 minimum.

Gotchas — read before shipping

  • Decorative walls must be aria-hidden AND contain no focusable elements — an <a> inside an aria-hidden wall is a broken tab stop (focusable but silent).
  • Give every image slot aspect-ratio + width BEFORE the image loads, or the loop desyncs as tracks change width mid-animation.
  • Three animated rows of images is real GPU work — keep tiles ≤300px wide, compress images (AVIF/WebP), and never run this behind another animation-heavy section.
  • Don't put critical brand names ONLY in the wall; it's invisible to assistive tech by design.

Browser support

ChromeSafariFirefoxEdge
114+17.5+121+114+

Floor set by text-wrap as this demo is written. The core technique itself goes back further — Chrome all.

aspect-ratio is baseline since 2021; everything else is plain CSS animation. Degrades to static collage under reduced motion by design.

Techniques used in this demo

Search CodeFronts

Loading…