Infinite Scroll Loop
`<pura-scroll-loop>` is the infinite looping scroller of awwwards portfolios and circular galleries: when the scroll reaches the end of the content it wraps around and continues from the start with no visible seam (Lenis infinite, Locomotive Scroll infinite mode). Unlike `<pura-infinite-scroll>`, which fires a load event for more data, nothing is loaded here; the same content repeats forever. The slotted content is cloned once into an `aria-hidden`, inert head clone and once into a tail clone; a passive scroll handler repositions the offset by exactly one copy-length when it crosses a seam, landing on identical pixels, so the jump is imperceptible. `axis="x"` loops horizontally, `disabled` restores a normal finite scroller, and the `loop` event reports each wrap with its direction. SSR, pre-JS, and reduced motion all render a single copy with normal scroll and a regular scrollbar. Size the host with `--pura-scroll-loop-height` or an inline height. Each instance registers in `window.__puraScrollLoops` by `data-pura-id` with `{ refresh, scrollToStart }`; `data-pura-loop-active` and `data-pura-loop-count` mirror live state.
Preview
<!-- vertical portfolio loop: scrolling past the last project wraps to the first -->
<pura-scroll-loop label="Projects" style="height: 100vh;">
<section class="project">Project one</section>
<section class="project">Project two</section>
<section class="project">Project three</section>
</pura-scroll-loop>
<!-- horizontal circular gallery; count the wraps -->
<pura-scroll-loop axis="x" label="Gallery" style="height: 320px;">
<img src="/photos/a.jpg" alt="A" style="height: 100%;" />
<img src="/photos/b.jpg" alt="B" style="height: 100%;" />
<img src="/photos/c.jpg" alt="C" style="height: 100%;" />
</pura-scroll-loop>
<script>
document.querySelector("pura-scroll-loop[axis=x]")
.addEventListener("loop", (e) => console.log("wrapped", e.detail.direction));
</script> Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
axis | "y" | "x" | y | Scroll axis of the loop. |
disabled | boolean | false | Turns the loop off; content scrolls normally and ends. |
label | string | Looping scroll gallery | Accessible name of the scroll region. |
Installation
pura is copy-paste and dependency-free. Load the whole library, or just this component.
<link rel="stylesheet" href="/pura/tokens.css">
<script type="module" src="/pura/lib/scroll-loop.js"></script> import "./pura/lib/scroll-loop.js";