3D✨ Premium

Parallax Tilt Gallery

A grid of six colored tiles where each tile reacts on its own according to its distance from the pointer: within 200 px it leans toward it (5° at most, at 100 px), grows up to 5% and gets a white glint at the spot you point at — nearby tiles move a lot, distant ones barely; mouse, finger or Tab key, and flat tiles (glint kept) when the user reduces motion.

JSMouseTilt

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

Six vinyl sleeves — "New in" racks of an independent record store — Parallax Tilt Gallery example 1

① Six vinyl sleeves — "New in" racks of an independent record store

WhenThe page of the week's new releases shows six sleeves in a grid; the sleeves near the mouse tip over and the glint slides across the hovered one, like on laminated cardboard.
WhyEach sleeve reacts according to its distance: you flip through the racks at a glance, which a single tilting card such as Perspective Tilt cannot do.
SettingsGrid widened to 340 px (tiles of about 100 px); 3 px corners; each sleeve has its own gradient and its title at the bottom left; dark band under the title of the striped sleeve; very dark brown background.
Crests of the twin towns — website of a twinning committee — Parallax Tilt Gallery example 2

② Crests of the twin towns — website of a twinning committee

WhenThe "Our twin towns" page lines up six crests (Germany, Italy, Poland, Ireland, Spain, Portugal) with the town name and the year of the twinning; the one you approach tilts and shines, its neighbors follow a little.
WhyThe decreasing reaction shows the six towns as one family: you point at one without dimming the others.
Settings340 px grid; white tiles with a 44 × 52 px crest cut by clip-path in the flag colors; glint switched to blue (rgba(37, 99, 235, .18)) to stay visible on white.
Sheet of six stamps from the new issue — website of a stamp club — Parallax Tilt Gallery example 3

③ Sheet of six stamps from the new issue — website of a stamp club

WhenThe club presents the "Marsh birds, 2027 issue" sheet: six perforated stamps; the glint under the mouse mimics gummed paper and the tilt the sheet you turn toward the light.
WhyA localized glint plus a distance-based tilt reproduces the gesture of examining a sheet of stamps under raking light.
Settings340 px grid; square corners; perforations drawn by a repeated radial gradient (radial-gradient(circle, #1d2433 3px, transparent 3.6px) every 12 px) on a #fbf7ec paper background, with the artwork set 7 px in.

How it works

The root .fx-0030-root (#0a0a0f background, at least 300 px tall) centers .tilt-gallery, a three-column grid (300 px wide at most, 10 px gaps) marked data-tilt-gallery. Its six .tilt-item are square (about 87 px), with 10 px corners, each with its own gradient (indigo, pink, green, amber, violet, red) and a white symbol ▲ ■ ◆ ★ ♥ ●. Each tile holds an empty .tilt-shine that covers it: a white radial gradient at 25% centered on --shine-x and --shine-y, invisible at rest, that appears on hover or focus.

The script looks for every [data-tilt-gallery] on the page. On each pointer move over the grid, it measures for each tile the distance between the pointer and its center, and derives an intensity that is 1 under the pointer and 0 at 200 px. The tile gets perspective(400px) rotateX(…) rotateY(…) scale(…): the side facing the pointer sinks, with an angle that grows with the offset and then falls with the intensity, so it peaks at 5° for a tile 100 px away; the tile right under the pointer barely tilts but grows by 5%. The glint of the hovered tile sits exactly under the pointer. A 0.3 s transition keeps the motion smooth; when the pointer leaves, every tile returns flat. Each tile carries its own perspective in its transform: no preserve-3d, so nothing a parent could flatten.

The script listens to pointer events: a pen or a finger makes the grid react, and touch-action: pan-y lets the page scroll vertically, only a sideways drag tilts the tiles. The tiles have tabindex="0": when one gets the focus, the script acts as if the pointer were at its center, so it grows, its glint lights up, and its neighbors lean toward it; when the focus leaves the grid, everything returns flat. In a real gallery, make each tile a link (<a>): the same code works, without tabindex.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, a block scoped to .fx-0030-root forces transform: none on the tiles and keeps only the shadow transition. The tiles stay flat; the white glint still follows the pointer and the shadow marks the hovered tile. Measured in Chromium, Firefox and WebKit: no tilt under the mouse (4° without the preference on the measured tile).
  • Keyboard: Tab moves from tile to tile; the active tile grows by 5%, lights up and gets a 2 px white outline offset by 3 px on :focus-visible, and its direct neighbors lean about 5° toward it. Measured in Chromium and Firefox: two Tab presses put the focus on the second tile, scaled to 1.05. Safari only gives Tab focus to links and fields unless the system keyboard option is turned on: use links for the tiles.
  • Screen readers: the symbols are read as they are ("black up-pointing triangle"…). In a real gallery, give each image a title or an alt and an explicit link; the .tilt-shine glint is empty and is not read.
  • Contrast: the white symbols are decorative; on the light ends of the gradients, white drops below 3:1 (1.7:1 on the amber #fbbf24, 1.9:1 on the green #34d399). For text inside the tiles, darken the gradient or add a dark band, like the "Néons" cover in the first scene.

Browser compatibility

CSS (perspective(), rotateX, rotateY and scale in each tile's transform, CSS variables inside a gradient, touch-action, :focus-visible) + JS with pointer and focusin / focusout events, no dependencies. Measured in Chromium 151, Firefox 153 and WebKit 26.5: same angles, same glint, two independent grids on one page, flat tiles under reduced motion; finger reaction measured in Chromium in touch mode. No preserve-3d: Playwright's WebKit renders these tilts like Chromium, but a real Safari was not checked.

Chrome 55+✓ Full
Firefox 59+✓ Full
Safari 13+✓ Measured on WebKit, not checked on a real Safari
Edge 79+✓ Full
Mobile iOS 13+✓ Not checked on a real iPhone
Android Chrome✓ Full, sideways drag

Without 3D transforms, the tiles grow without tilting; the glint and the shadow remain. Without :focus-visible, the browser's default focus ring shows instead.

The code

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

index.html — structure
<div class="fx-0030-root">
  <div class="tilt-gallery" data-tilt-gallery="">
    <div class="tilt-item" tabindex="0">
      <span class="tilt-shine"></span>▲
    </div>
    … (6 tiles)
  </div>
</div>

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

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Reach (JS — maxDist = 200) 200 px Distance beyond which a tile stops reacting. At 120 only the direct neighbors move; at 300 the whole grid ripples.
Tilt strength (JS — the 20 factor of rotX and rotY) 20 (5° at most, at half the reach) The maximum angle is a quarter of this factor: 40 gives 10° for the tile 100 px from the pointer.
Growth (JS — 0.05 in scale) 5% 0.1 makes the hovered tile stand out clearly; at 0 only the tilt remains.
Perspective (JS — perspective(400px)) 400px Small value, strong distortion. Change it in the reset() function as well.
Glint (CSS — .tilt-item .tilt-shine) rgba(255, 255, 255, .25), transparent 60% On white tiles, switch to a tint (blue at .18 in the second scene); for a sharper glint, lower 60% to 40%.
Grid size (CSS — max-width: 300px and grid-template-columns of .tilt-gallery) 300 px, 3 columns The reach is in pixels: if you make the tiles much larger, raise maxDist accordingly to keep the neighborhood effect.
Speed (CSS — transition: transform .3s of .tilt-item) 0.3 s 0.15 s for lively tiles, 0.5 s for a heavier motion.

FAQ

The angle depends on the offset between the pointer and the tile's center: right above it, that offset is zero. The targeted tile grows and lights up, and its neighbors lean toward it, at most 5° at 100 px. That is what makes the grid feel like it turns toward the pointer rather than six separate cards.
Perspective Tilt is a single card that follows the pointer over its own surface, up to 12°, with raised text. Parallax Tilt Gallery spreads the reaction over several tiles according to their distance from the pointer, with smaller angles. One piece to showcase: Perspective Tilt; a collection to browse: Parallax Tilt Gallery.
Yes: the script handles every .tilt-item in the grid, whatever their number. The colors are set by :nth-child(1) to (6): add rules for the next ones. Each move measures every tile: for a very large grid, split it into several data-tilt-gallery grids, each gets its own instance.