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 collection to your <body>:
Copy the main[data-squiggle] element from index.html, then replace the images, names, prices and product IDs. The demo includes eight products. Extra visual copies are added automatically when a wider stage needs them. The included assets/demo.js provides a local demonstration bag; it does not create orders or connect to a checkout.
Using It With Your Own Design
The script needs a data-squiggle root containing data-squiggle-viewport, data-squiggle-track and equal-width data-squiggle-card elements. Each product action uses data-squiggle-buy="your-product-id"; its card needs an h2 for the product name. Native buttons and links inside cards retain their normal behaviour. The script emits an event only for elements with the buy hook.
The photographs, font, collection header, prices, colour tokens and demo bag are replaceable styling. The optional SVG contains a data-squiggle-path path; it shows the route behind the cards. Keep its sizing and the is-live positioning rules when restyling. The track gap supplies the card pitch. Cards must share a width. The script repeats complete collections as needed to cover the viewport plus two card widths, keeping the wrap out of sight even on ultrawide displays. Copies preserve product IDs, so their actions refer to the same products; do not put ID-dependent widgets inside the cards. Resizing or teardown removes surplus copies.
Without JavaScript the track is a native horizontal flex rail. Absolute positioning is enabled only after the animation initializes. Keep that fallback, the viewport's clipped overflow in motion mode, and touch-action: pan-y so a vertical touch gesture can still scroll its parent page. No device-orientation permission is needed: this is a swipe rail.
Options
| Attribute | Values | Default | Description |
|---|---|---|---|
data-squiggle |
Root hook | Required | Scopes one independent gallery |
data-squiggle-amplitude |
0–1.3 |
1 |
Responsive wave depth multiplier |
data-squiggle-prev |
Button hook | Optional | Browse backward |
data-squiggle-next |
Button hook | Optional | Browse forward |
data-squiggle-position |
Text hook | Optional | Current position and product count |
data-squiggle-path |
SVG path hook | Optional | Visible winding guide |
data-squiggle-buy |
Product ID | Optional | Emits the product action event |
data-squiggle-live |
Status hook | Optional | Demo bag feedback; use role="status" |
Accessibility
Previous/next buttons, left/right arrow keys, pointer drag, touch swipe and wheel input browse the rail. Focusing a visible product action brings its card into view. Cards fully outside the stage are inert so they do not create invisible tab stops. A swipe suppresses the resulting click. Product buttons have explicit accessible names; focus receives the same treatment as hover and a visible outline.
Reduced motion removes the animated path and uses a scrollable product rail with working controls and product actions. With JavaScript disabled, products remain readable and horizontally scrollable; connect commerce actions to your own progressively enhanced forms if purchases must also work without scripting.
Dependencies
- GSAP 3.15.0 core; no plugins or Lenis required.
- Mona Sans from Google Fonts is optional demo typography.
- Product photographs are bundled as WebP; replace them with your own product assets.
Teardown
JavaScript — before removing this demo in an SPA:
Code snippet omitted: it ships with the download.
Cleanup removes the ticker, pending snap, event listeners, resize/intersection observers, pointer capture and animation styles. This global context handle is for the standalone demo; retain a separate context handle per mounted instance in a component application.
Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.