3D✨ Premium

Perspective Scroll

Four colored panels ("Layer 1" to "Layer 4") are born 1,200 px deep and rush toward the screen until they fly past it in 8 s, one every 2 s, each with its own offset: a tunnel of panels in pure CSS (perspective, translateZ, depth sorting), with no scrolling and no JavaScript despite the name, laid out as a still staircase when the user reduces motion.

CSSPerspective3D

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. 3D has 50 effects, including 8 free. Explore the category →

3 usage examples

Time travel through the town — digital exhibition of a local history museum — Perspective Scroll example 1

① Time travel through the town — digital exhibition of a local history museum

WhenRoom 2 of the online exhibition: four panels, "1850 — the mill", "1914 — the station", "1968 — the factory", "2026 — the media library", arrive from the back one after the other over a sepia background, under the exhibition title.
WhyDates surging from the distance up to you read as a journey toward the present, in chronological order since the panels arrive in HTML order. A horizontal timeline would be something to read; here, you watch time coming.
SettingsRoot without background and a 360 px container over a sepia gradient; panels enlarged to 224 × 86 px, cream paper #efdfbf, #a8865a border, year in 28 px Georgia; wider offsets (--fx0024-x from −105% to +5%) to alternate left and right; original duration and delays.
Wine route signs coming closer — website of a tourist route — Perspective Scroll example 2

② Wine route signs coming closer — website of a tourist route

WhenAt the top of the route page: a road running to the horizon between rows of vines, and brown signs, "Riquewihr 4 km", "Wine cooperative", "Kaysersberg 9 km", growing as if seen from the car, above the "Plan my route" button.
WhyThe vanishing point of the perspective sits at the center of the container: by putting the end of the road there, the panels arrive exactly from where the car is heading. Arriving from the back recreates the driver's view; it is an invitation to hit the road.
Settings360 px container, road drawn with clip-path with its tip at the center (270, 180); 204 × 70 px panels in brown #6e3f1f with a 3 px white border; --fx0024-x offsets from +40 to +55% (right roadside) and −145% for one sign on the left, --fx0024-y around −70% to stay at horizon height.
End credits of the dance recital — online video of a dance school — Perspective Scroll example 3

③ End credits of the dance recital — online video of a dance school

WhenAfter the last choreography, the video goes black and the credits fly toward the viewer: "Choreography — Léa M.", "Lighting — Sam", "Costumes — parents' workshop", "Thank you to 84 dancers".
WhyNames rushing toward the audience make a stage finale, and the 8 s loop replays the credits for as long as the video stays on its end screen. No other effect in the category brings content in from the depth.
SettingsNear-black purple background; 232 × 86 px panels, rgba(24, 12, 34, .72) background, gold #d8b46a outline, role in small gold capitals and name in 25 px Georgia; offsets from −115% to +15% to open the tunnel; mock playback bar at the bottom.

How it works

The root .fx-0024-root (#0a0a0f background, at least 300 px tall, overflow: hidden) holds the .perspective-scroll-container (full width × 250 px, perspective: 500px) and four .perspective-plane elements placed at the center: indigo 120 × 60 px, pink 100 × 50, green 140 × 70 and amber 90 × 45, all 70% opaque. A single animation, fx0024Fly, linear over 8 s, moves them from translateZ(-1200px) to translateZ(200px); opacity goes from 0 to 1 over the first 10 percent, stays at 1 until 80%, then drops back to 0. With a 500 px perspective, a panel shows at 29% of its size at the start (500 / 1,700) and 167% at the end (500 / 300): it grows almost six times during its flight, then fades before passing "behind" the viewer.

Each panel carries two variables, --fx0024-x and --fx0024-y (−50% / −50% = centered; then −80% / −80%, −20% / −30%, −70% / −20%), used in both steps of the keyframes: the offset holds for the whole flight, and since the perspective enlarges it along with the panel, the four spread away from the center as they approach, like the walls of a tunnel. Delays are negative (0, −6, −4 and −2 s): as soon as the page loads, the four panels are already in flight at four different depths, 2 s apart, and a new panel arrives every 2 s. Measured in Chromium 151 and Firefox 153: 5.4 to 5.8% of the scene's pixels change over 0.8 s, and both read the variables inside the keyframes.

The container has transform-style: preserve-3d: panels are sorted by depth, and the one coming close passes in front of the one leaving the back. That is why the container has no overflow and the root does the clipping: measured in Chromium and Firefox, overflow: hidden and even overflow: clip on the container flatten the scene, and the panels are then painted in HTML order, a distant panel on top of a near one. Not a single line of JavaScript: the browser animates four transform and four opacity values. The catalog name says "Scroll", but nothing listens to scrolling: the loop runs on its own, wherever you place the effect.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, a block scoped to .fx-0024-root stops the animation and lays the four panels out as a staircase, from −600 px (top left) to 0 px (bottom right): a still image of the tunnel where every label stays readable. Measured: 0% of pixels change over 0.8 s in Chromium, Firefox and WebKit (5.4 to 5.8% without the preference). This setting matters more here than elsewhere: content rushing toward the viewer is the kind of motion that bothers people prone to dizziness.
  • Text: the labels are real text, read by screen readers in HTML order whatever the panel's position. On screen, each one is readable for only a few seconds per loop: do not give the panels information that exists nowhere else, as the scenes above show (the list of dates or names stays in the page).
  • Contrast: white text on 70% panels over #0a0a0f, calculated at 7.3:1 on indigo, 6.2:1 on pink, 4.6:1 on green and 4.0:1 on amber. Amber stays under the 4.5:1 threshold for small text: darken it or switch its text to black if the label must be read. During the fade-in and fade-out, contrast drops with opacity.
  • Pace: one continuous 8 s loop, with no flashing and no sudden change in brightness; no interaction, nothing to reach with the keyboard.

Browser compatibility

CSS only: perspective, transform-style: preserve-3d, translateZ and CSS variables read inside @keyframes, zero JavaScript, no dependencies. Measured in Chromium 151 and Firefox 153: same flight, same depth sorting, same stop under reduced motion; two copies of the effect on one page work (no ids). Playwright's WebKit (26.5) flattens all CSS 3D, even a reference cube: rendering in Safari has not been verified on a real Safari.

Chrome 49+✓ Full
Firefox 31+✓ Full
Safari 9.1+✓ Not verified on a real Safari
Edge 79+✓ Full
Mobile iOS✓ Not verified on a real device
Android Chrome✓ Full

If a rule on your page adds overflow, filter or an opacity below 1 to the container, the scene is flattened (measured in Chromium and Firefox for all three): the panels still fly, but stack in HTML order instead of being sorted by depth. The labels remain text in the page, even when the animation is not running.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0024-root">
  <div class="perspective-scroll-container">
    <div class="perspective-plane plane-1">Layer 1</div>
    <div class="perspective-plane plane-2">Layer 2</div>
    <div class="perspective-plane plane-3">Layer 3</div>
    <div class="perspective-plane plane-4">Layer 4</div>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Speed (CSS — 8s in the four animation declarations) 8 s, delays 0 / −6 / −4 / −2 s Change the four durations together and keep delays equal to 0, −¾, −½ and −¼ of the duration: at 12 s, use 0 / −9 / −6 / −3 s. A panel then arrives every 3 s instead of 2.
Flight depth (CSS — translateZ(-1200px) and translateZ(200px) in the keyframes) −1,200 px → +200 px A more distant start makes the panel smaller at first (−2,000 px: 20% of its size). The end must stay below the perspective value (500 px): beyond it, the panel is behind the viewer and disappears.
Perspective (CSS — .perspective-scroll-container) 500px Smaller, the growth is more abrupt: at 300 px, a panel goes from 20% to 300% of its size. Larger (900 px), the flight becomes a gentle glide. If you lower it below 200 px, lower the end of the flight too.
Offsets (CSS — --fx0024-x and --fx0024-y on each .plane-N) −50 / −50%, −80 / −80%, −20 / −30%, −70 / −20% As a percentage of the panel's size; −50% = centered. The further from −50%, the more the panel moves away from the center as it approaches: from −110% to +10%, the tunnel opens clearly; positive values (+40%) send every panel to the same side, like roadside signs.
Panels (HTML and CSS — .perspective-plane, .plane-1 to .plane-4) 4 panels, 90 to 140 px wide, 70% colors Put any text or image in a panel. For a fifth panel, copy a .plane-N rule and spread the delays over the duration (8 s / 5 = one delay every −1.6 s). Larger panels (200 px and up) make the labels readable earlier in the flight.
Background and frame (CSS — .fx-0024-root) #0a0a0f, at least 300 px tall Change or remove the root's background to set the tunnel on your own backdrop. Keep its overflow: hidden: it is what clips the enlarged panels, since the container must not have one.

FAQ

It is the catalog name. The sold code is an automatic loop: no scroll listener, no JavaScript. The panels fly from the back toward the screen whether the page moves or not. If you want the flight to follow scrolling, you have to drive the animation yourself (for example by pausing it and setting its progress from a script), which this code does not do.
Because it would flatten the scene. Measured in Chromium 151 and Firefox 153: with overflow: hidden, and even with overflow: clip, on the element that has preserve-3d, the panels are no longer sorted by depth and are painted in HTML order: a distant panel passes over a near one. Clipping is therefore left to the root .fx-0024-root, one level up. filter and an opacity below 1 on the container have the same effect (also measured).
Immersive Depth Scroll places layers at fixed depths and slides them according to the mouse position: the content stays put, the point of view moves. Perspective Scroll moves the panels themselves from the back all the way to the viewer, in a loop and with no interaction. Pick Perspective Scroll for credits, a timeline or an arrival; a mouse-driven effect for a scene to explore.