
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:
--width
and--height
to size each item--quantity
to set how many elements are in the loop--duration
for 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 ❤️