021

Hover Image Trail

£10 or the whole Vault, £99

Velocity-aware image trail for a list of links: layered card drift, directional tilt, staggered decay, and static touch previews. Every card keeps its own photograph's shape. Pure GSAP core.

intermediate
4 more details
cursor-effectshover-effectimage-trailmicro-interaction

This demo reads better at your own screen size than in the frame below:

Updated

About this effect

A physical image-trail effect that turns fast pointer sweeps across a list of links into layered fans of photographs. Pointer velocity drives each card's travel, tilt and scale, and each card is sized from its own image, so landscape, portrait and square frames fan out together at an even visual weight. A reusable pool keeps the DOM bounded; keyboard and touch users receive clear static previews instead.

Hover Image Trail - GSAP animation effect preview

What's included

8 items
  • Distance-threshold spawning: a new image appears after the pointer travels a configurable distance
  • Velocity-aware motion: images tilt and drift in the direction the cursor is moving
  • Fixed element pool with round-robin reuse: no unbounded DOM growth
  • Per-row or per-container image sets via child img elements or data-trail-images JSON
  • Configurable image size, spawn threshold, lifetime, and pool size via data attributes
  • Keyboard support: focusing a row reveals its image statically, mirroring hover
  • Accessible fallbacks: visible touch previews plus a static focus/reduced-motion reveal
  • Zero plugins required: GSAP core only, works alongside any other effects

Perfect for

5 use cases
  • Portfolio and agency project lists with per-project preview imagery
  • Case study indexes where hovering a row teases the work
  • E-commerce collection menus revealing product shots on hover
  • Editorial article lists with trailing cover images
  • Award-style landing pages that need a memorable signature interaction

How it works

3 sections

A pointermove listener reads distance and elapsed time, filling in spawn points along fast sweeps so a single event can still build a layered fan. Speed maps to drift, tilt and scale, then cards fade and shrink in spawn order after the configured lifetime.

Images come from a fixed pool reused round-robin, with tween cleanup so an interrupted card never fights its replacement. Each card reads its source's width and height from the markup and is sized to a common area, so the proportions vary while the visual weight does not.

Motion is enabled only for fine pointers without reduced motion. Keyboard focus uses one static card, while touch devices keep or generate one visible representative preview per row.

Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Hover Image Trail opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

2. Add before closing </body>:

Code snippet omitted: it ships with the download.

3. Add the effect to your <body>:

Code snippet omitted: it ships with the download.

Give each source image its width and height attributes. That is where a card's shape comes from, and having it in the markup means the first card is correctly proportioned before any image has decoded; without them the script falls back to the decoded dimensions, and to 4:3 for an image that has not loaded yet.

The container is the trail's positioning context, so give it position: relative. Each .trail-item supplies its own image cycle; .trail-item__preview is hidden while a fine pointer is present and shown on coarse pointers, where there is no hover to trail. Drop it and the script creates one per row instead.

Options

Set options on the [data-image-trail] container:

Attribute Values Default Description
data-trail-images JSON array — Container-level fallback image list: URL strings, or { "src", "width", "height" } objects that carry each shape
data-trail-threshold Pixels 82 Travel distance between card spawns
data-trail-lifetime Milliseconds 620 Delay before each card settles out
data-trail-size Pixels 224 Card size: the width a 4:3 card takes. Every card is scaled to that same area, so shapes differ while visual weight does not
data-trail-max Integer 9 Maximum pooled floating cards

data-trail-images also works on an individual .trail-item and takes priority over child images.

CSS Hooks

Selector Purpose
[data-image-trail] Tracked positioning context
.trail-item Focusable source row
.trail-item__title Row label; styled by the demo, not read by the script
.trail-item.is-active Current pointer/focus row response
.trail-item__preview Persistent coarse-pointer preview
.image-trail__img Pooled floating card created by the script. Its width and height are set inline per card, so do not give it an aspect-ratio in CSS or every card collapses back to one box
.image-trail__img--focus Single static keyboard/reduced-motion card

Accessibility

  • Keyboard: use links or buttons for .trail-item; focus shows the row's first image at the end of the row and mirrors the active state.
  • Reduced motion: the moving trail is disabled. Fine-pointer hover and keyboard focus use one static card with no animated travel.
  • Touch: every row keeps a representative image visible. Tapping or focusing the row activates its typography and accent treatment.
  • Screen readers: generated and decorative previews use empty alt text and aria-hidden="true"; project names remain the accessible content.
  • No JavaScript: all row text remains visible, and authored .trail-item__preview images remain visible on mobile.

Dependencies

  • GSAP 3.12+ core (GSAP 3.15.0 CDN shown above)
  • No GSAP plugins required
  • No smooth-scroll library required

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.