The "trusted by" logo strip is on every B2B landing page in existence, and an alarming number of them ship a carousel library to make it drift sideways. That's a JavaScript dependency, main-thread animation work, and a layout-shift risk — for logos that scroll.
The whole effect is one CSS keyframe. Velocity X's logo-ticker is a free, MIT-licensed .astro component built on exactly this pattern — install it and read the whole thing in a minute.
The Money Pattern
<div class="overflow-hidden">
<div class="flex w-max gap-12 animate-[ticker_30s_linear_infinite]">
<ul class="flex shrink-0 gap-12">…logos…</ul>
<ul class="flex shrink-0 gap-12" aria-hidden="true">…same logos…</ul>
</div>
</div>
@keyframes ticker {
to { transform: translateX(-50%); }
}
Two identical tracks sit side by side; the animation slides the pair exactly one track-width (−50%) and loops. Frame 0 and frame N are pixel-identical, so the loop point is invisible. The compositor runs the transform off the main thread — it stays smooth while your JS bundle is still parsing.
The Catch
Three details separate this from the janky version. First, the seam: -50% is only seamless if the duplicate is exactly identical — same gap before the first logo as after the last, which is why the gap lives on the track, not as track padding.
Second, w-max on the moving element. Without it the flex container clamps to the viewport and the percentage translates against the wrong width — the classic "my ticker jumps" bug.
Third, the duplicate track is aria-hidden and the whole strip respects prefers-reduced-motion — a permanently moving element is an accessibility failure, not a vibe. Wrap the animation in a motion-safe: variant and the reduced-motion version is just a static logo row.
The Verdict
Spoiler: the library version renders the same pixels with ~30KB more JavaScript. This is the pattern across the free tier of Velocity X — 40 MIT components, CSS doing the work wherever CSS can. The free tier's source is public on GitHub — no account, no key (the velocityx CLI is in preview, not on npm yet).









