More Animations Snippets
3D Marquee — Free HTML CSS JS Perspective Gallery Snippet
3D Marquee · Animations · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
3D Marquee — Tilted Perspective Wall of Scrolling Tiles

The 3D marquee is the dramatic hero backdrop where a grid of image tiles is tilted back in perspective like a wall receding into the distance, with its columns endlessly scrolling in alternating directions — a living gallery behind your headline. This snippet builds it with plain HTML, CSS 3D transforms, and a little vanilla JavaScript to populate and loop the tiles.
Tilting the grid into perspective
The scene is a four-column CSS grid that's transformed with rotateX(52deg) rotateZ(-42deg). That combination lays the wall back and rotates it diagonally, so the flat grid reads as a large surface angling away into space — the signature isometric-ish look. It's sized larger than the viewport (1100×1100) and centered with translate(-50%, -50%) so the tilted plane covers the whole hero with no visible edges. No perspective property is needed here because the rotation alone, at this scale, produces the receding-wall illusion.
Columns that scroll in opposite directions
Each column animates vertically, but adjacent columns move opposite ways: columns marked data-dir="1" run the tmUp keyframe (translating to -50%), while data-dir="-1" columns run tmDown (from -50% back to 0). The counter-motion is what gives the wall its dynamic, woven feel — a single direction would look like one flat conveyor. Both keyframes are pure CSS, so the browser's compositor drives the scroll efficiently.
Seamless looping by duplication
To loop endlessly, each column is filled with a set of tiles and then an exact clone of that set, so the column is two identical halves. Animating by 50% (one half's height) means that when a column reaches the end of the first set, the cloned second set sits precisely where the first began — so the keyframe restart is invisible. The tiles are built in JavaScript and cloned with cloneNode(true), which is both concise and guarantees the two halves match exactly.
Image-free, themeable tiles
Each tile is a 4:3 rounded rectangle filled with a random gradient from a palette, with a soft drop shadow so the wall has depth. Using gradients keeps the snippet dependency-free and the wall colorful; swap the --g background for real image URLs to turn it into a portfolio or product wall without changing the layout or loop logic.
Keeping the headline readable
A radial .tm-overlay darkens the scene from a translucent center to near-opaque edges, so the bright tiles don't fight the text. The content sits above at a higher z-index with a soft text-shadow, so the headline stays crisp and centered over the busy, moving backdrop.
Customizing it
Change the rotateX/rotateZ angles to steepen or flatten the wall, adjust the animation duration for a faster or calmer drift, add or remove columns (each picks up its own direction from data-dir), or swap gradients for images. Tune the overlay stops to reveal more or less of the gallery. Pair it with a hero parallax grid elsewhere or a text generate headline for a bold landing page.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA tilted wall of colorful tiles fills the hero behind a headline.
- 2Watch the motionColumns scroll up and down in alternating directions, endlessly.
- 3Note the perspectiveThe grid angles away like a receding surface.
- 4Read the headlineA radial overlay keeps the centered text legible.
- 5Swap in imagesSet each tile's --g to a real image URL.
- 6Adjust the tiltChange the rotateX and rotateZ angles.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
The four-column grid is transformed with rotateX(52deg) and rotateZ(-42deg), which lays it back and rotates it diagonally so the flat grid reads as a surface receding into space. It's sized larger than the viewport and centered so the tilted plane covers the whole hero with no visible edges.
Each column is filled with a set of tiles and an exact clone of that set, making it two identical halves. The columns animate by 50% — one half's height — so when the first set scrolls away, the cloned set sits exactly where it began. The keyframe restart lands on an identical frame, so the loop is seamless.
Columns marked data-dir 1 run an upward keyframe and those marked -1 run a downward one. The counter-motion gives the wall a woven, dynamic feel; if every column scrolled the same way it would look like a single flat conveyor belt. Both keyframes are pure CSS so the compositor handles them efficiently.
Yes. Each tile is a 4:3 rounded box whose background comes from a --g custom property, set to a random gradient by default. Replace --g with a url() image (or swap the div for an img), and the perspective tilt, alternating scroll, and seamless loop all keep working unchanged.
Render the columns and generate the doubled tile lists from a data array in render. The tilt, alternating keyframes, and overlay are pure CSS. If you swap to images, map your URLs into the tiles. In Tailwind, build the grid with grid utilities, apply the rotateX/rotateZ via arbitrary transform values, and define the scroll keyframes in the config.