Still using JavaScript for an autoplay carousel?
You don’t need to anymore.
A one-directional, looping logo strip can now be built entirely with CSS.
No setInterval. No libraries. No layout shifts.
Here’s how it works: You define a few CSS custom properties:
--widthand--heightto size each item--quantityto set how many elements are in the loop--durationfor how long one full cycle takes
Each item gets a --position, so we can stagger its animation using animation-delay.
This formula spaces each item evenly:
calc((var(--duration)/var(--quantity)) * (var(--position) - 1) - var(--duration))
It ensures that the track starts full, no empty gaps at load.
The animation itself is simple:
From left: 100% to left: -width, sliding items across the track.
We use position: absolute so every item animates independently,
and overflow: hidden on the container to act as a viewport.
For a smooth entrance and exit, we apply a mask-image gradient.
This fades logos in/out without extra DOM or performance hits.
Accessibility? Covered.
Each logo gets tabindex="0" so keyboard users can focus them,
and the entire animation pauses on hover or focus using :has(:focus) and animation-play-state: paused.
No JavaScript.
Just CSS, doing what used to take 100KB+ of JS.
Checkout the codepen: https://codepen.io/theosoti/pen/OPVeegy
To learn more tips about CSS, make sure to join my newsletter below ❤️