Infinite Scrolling Logos with HTML and CSS

Build smooth, performant logo carousels using pure CSS--no JavaScript required. Learn the keyframe animation technique for seamless infinite scrolling.

Why Use Infinite Scrolling Logos?

Infinite scrolling logo carousels have become a staple in modern web design, appearing on countless agency websites, product pages, and portfolio sites to showcase client work, technology partnerships, or brand collaborations. They create visual interest without requiring user interaction, making them perfect for:

  • Social proof through visual presentation of trusted clients
  • Technology showcases displaying partnership logos (React, Node.js, AWS)
  • Brand collaborations highlighting business relationships
  • Visual polish adding subtle motion to otherwise static pages

This guide covers building performant, accessible logo animations using pure CSS, as part of our comprehensive web development services.

Key Benefits

Why choose CSS-only infinite scrolling for your logo carousel

Performance

CSS transforms are GPU-accelerated, ensuring smooth 60fps animations without JavaScript overhead.

Accessibility

Native CSS media queries let you respect user preferences for reduced motion automatically.

Responsive

CSS variables and media queries make it easy to adapt carousels for any screen size.

Maintainable

No JavaScript dependencies means less code to test, debug, and maintain over time.

HTML Structure

The semantic structure for an infinite scrolling logo carousel requires a few key elements:

  1. Container - A section element with proper ARIA labeling
  2. Track - An inner element holding all logos in a flex row
  3. Logo items - Individual containers for each logo
  4. Duplicate set - A second copy of all logos for seamless looping

Accessibility Tip: Always include aria-label on the carousel section to describe its purpose for screen reader users.

HTML Structure for Logo Carousel
1<section class="logo-carousel" aria-label="Our trusted partners">2 <div class="logo-track" style="--gap: 2rem;">3 <!-- First set of logos -->4 <div class="logo-item">5 <img src="client-1.svg" alt="Acme Corporation" />6 </div>7 <div class="logo-item">8 <img src="client-2.svg" alt="TechStart Inc" />9 </div>10 <div class="logo-item">11 <img src="client-3.svg" alt="Global Solutions" />12 </div>13 <!-- Add more logos as needed -->14 15 <!-- Duplicate set for seamless infinite scroll -->16 <div class="logo-item">17 <img src="client-1.svg" alt="Acme Corporation" />18 </div>19 <div class="logo-item">20 <img src="client-2.svg" alt="TechStart Inc" />21 </div>22 <div class="logo-item">23 <img src="client-3.svg" alt="Global Solutions" />24 </div>25 </div>26</section>

CSS Animation Fundamentals

The core technique relies on CSS keyframes and the transform property. Modern browsers handle translateX() efficiently because it's GPU-accelerated, meaning the animation runs on the compositor thread separate from the main layout thread.

Key concepts:

  • Use linear timing for consistent speed throughout
  • The to value must calculate both the width AND the gap between items
  • Animation duration typically ranges from 20-60 seconds depending on logo count
CSS Keyframe Animation for Infinite Scroll
1.logo-track {2 display: flex;3 gap: var(--gap, 2rem);4 width: max-content;5 animation: scroll 40s linear infinite;6}7 8@keyframes scroll {9 from {10 transform: translateX(0);11 }12 to {13 transform: translateX(calc(-100% - var(--gap, 2rem)));14 }15}16 17.logo-item {18 flex: 0 0 150px;19 height: 80px;20 display: flex;21 align-items: center;22 justify-content: center;23}24 25.logo-item img {26 max-width: 100%;27 max-height: 100%;28 object-fit: contain;29}

How the Seamless Loop Works

The "magic" of infinite scrolling is actually quite simple:

  1. We display two identical sets of logos side by side
  2. As the animation runs, the track slides left continuously
  3. When the animation reaches 50%, we've scrolled exactly one complete set
  4. At this point, the second set is in the position the first set started
  5. The animation instantly resets to 0%
  6. Since both sets are identical, users cannot detect the reset
  7. This creates the perfect illusion of endless scrolling

The gap calculation is critical: calc(-100% - gap) ensures the track moves exactly the width of one set plus all the gaps between items.

Responsive Design Considerations

Logo carousels need to adapt across device sizes. On smaller screens, you typically want to:

  • Show fewer logos at once (2-3 instead of 5-6)
  • Slow the animation slightly for readability
  • Reduce the size of individual logo containers
  • Adjust gaps for better proportion

Proper responsive design is essential for performance optimization on mobile devices.

Responsive Breakpoints for Logo Carousel
1/* Tablet breakpoint */2@media (max-width: 1024px) {3 .logo-item {4 flex: 0 0 120px;5 height: 70px;6 }7 8 .logo-track {9 animation-duration: 35s;10 }11}12 13/* Mobile breakpoint */14@media (max-width: 768px) {15 .logo-item {16 flex: 0 0 100px;17 height: 60px;18 }19 20 .logo-track {21 animation-duration: 25s;22 }23 24 .logo-carousel {25 -webkit-mask-image: linear-gradient(26 to right,27 transparent,28 black 5%,29 black 95%,30 transparent31 );32 }33}

Performance Optimization

For smooth 60fps animations, follow these performance guidelines:

Use GPU-Accelerated Properties

Only animate transform and opacity--these are handled by the GPU compositor thread and don't trigger layout recalculations. This approach aligns with our web development best practices for building high-performance websites.

Optimize Images

  • Use SVGs for logos when possible (resolution-independent, smaller file size)
  • Compress raster images appropriately
  • Specify explicit dimensions to prevent layout shift

Reduce Paint Operations

  • Avoid animating properties like width, height, margin, or padding
  • Use will-change: transform sparingly as a hint to the browser

Optimized animations contribute to better SEO performance and user experience.

Accessibility Best Practices

Creating inclusive logo carousels means considering users with motion sensitivity and screen reader users.

Respect Motion Preferences

The prefers-reduced-motion media query allows users who are sensitive to motion to see a static display:

@media (prefers-reduced-motion: reduce) {
 .logo-track {
 animation: none;
 }
}

Screen Reader Considerations

  • Add descriptive aria-label to the carousel section
  • Provide meaningful alt text for each logo
  • Consider a visually hidden list as an alternative for screen readers
  • Don't animate too quickly (under 3 seconds per cycle) as screen readers may struggle to parse content
Accessibility: Reduced Motion Support
1/* Respect users who prefer reduced motion */2@media (prefers-reduced-motion: reduce) {3 .logo-track {4 animation: none;5 flex-wrap: wrap;6 justify-content: center;7 gap: 1.5rem;8 }9 10 .logo-item {11 flex: 0 0 calc(33.333% - 1rem);12 }13}14 15/* Interactive enhancement: pause on hover */16.logo-track:hover {17 animation-play-state: paused;18}

Common Implementation Pitfalls

The Gap Calculation Problem

The most common issue is mismatched gap calculations. If your CSS gap is 2rem but your translate calculation only uses -100%, you'll see a visible jump when the animation resets.

Solution: Always calculate the gap into your translate value: translateX(calc(-100% - var(--gap, 2rem)))

Uneven Logo Sizes

Logos with different aspect ratios can cause visual jarring:

Solutions:

  • Use fixed-height containers with object-fit: contain
  • Normalize logo dimensions before upload
  • Wrap logos in uniform containers with CSS

Performance on Lower-End Devices

Older devices may struggle with animations:

Mitigations:

  • Test on representative devices
  • Use translate3d() to force GPU
  • Consider prefers-reduced-motion detection for slower devices
  • Provide a manual scroll fallback for problematic devices

Advanced Variations and Enhancements

Gradient Fade Effects

Add visual polish with mask gradients on either side of the carousel:

.logo-carousel {
 -webkit-mask-image: linear-gradient(
 to right,
 transparent,
 black 10%,
 black 90%,
 transparent
 );
 mask-image: linear-gradient(
 to right,
 transparent,
 black 10%,
 black 90%,
 transparent
 );
}

Vertical Scrolling Logos

For a different visual effect, use vertical scrolling:

.logo-track {
 display: flex;
 flex-direction: column;
 animation: scroll-vertical 30s linear infinite;
}

@keyframes scroll-vertical {
 from { transform: translateY(0); }
 to { transform: translateY(calc(-100% - var(--gap, 2rem))); }
}

Pause on Hover

Allow users to inspect logos more closely:

.logo-track:hover {
 animation-play-state: paused;
}

Complete Production Example

Here's a production-ready implementation combining all the concepts covered in this guide:

HTML Structure:

<section class="clients-section" aria-labelledby="clients-heading">
 <h2 id="clients-heading" class="visually-hidden">Our Clients</h2>
 <div class="logo-carousel">
 <div class="logo-track" style="--gap: 2rem;">
 <div class="logo-item">
 <img src="client-1.svg" alt="Acme Corporation" />
 </div>
 <div class="logo-item">
 <img src="client-2.svg" alt="TechStart Inc" />
 </div>
 <!-- More logos... -->
 <!-- Duplicate set -->
 <div class="logo-item">
 <img src="client-1.svg" alt="Acme Corporation" />
 </div>
 <div class="logo-item">
 <img src="client-2.svg" alt="TechStart Inc" />
 </div>
 </div>
 </div>
</section>

CSS Styles:

.clients-section {
 padding: 4rem 0;
 overflow: hidden;
 background: #f8f9fa;
}

.logo-carousel {
 width: 100%;
 max-width: 1200px;
 margin: 0 auto;
 -webkit-mask-image: linear-gradient(
 to right, transparent, black 5%, black 95%, transparent
 );
}

.logo-track {
 display: flex;
 gap: var(--gap, 2rem);
 width: max-content;
 animation: scroll 40s linear infinite;
}

.logo-item {
 flex: 0 0 150px;
 height: 80px;
 display: flex;
 align-items: center;
 justify-content: center;
}

.logo-item img {
 max-width: 100%;
 max-height: 100%;
 object-fit: contain;
}

@keyframes scroll {
 from { transform: translateX(0); }
 to { transform: translateX(calc(-100% - var(--gap, 2rem))); }
}

@media (max-width: 768px) {
 .logo-item { flex: 0 0 100px; height: 60px; }
 .logo-track { animation-duration: 25s; }
}

@media (prefers-reduced-motion: reduce) {
 .logo-track { animation: none; }
}

.logo-track:hover { animation-play-state: paused; }

Summary

Infinite scrolling logos add visual interest and social proof to websites without requiring user interaction. With modern CSS, you can create smooth, performant animations that respect user preferences and work across devices.

Key takeaways:

  1. Use transform: translateX() for performant, GPU-accelerated animations
  2. Duplicate content creates the seamless loop illusion--display two identical sets
  3. Include prefers-reduced-motion support for accessibility
  4. Calculate gap carefully in your translate value for seamless transitions
  5. Optimize images for fast loading
  6. Use responsive breakpoints to adapt for different screen sizes
  7. Test across devices to ensure smooth performance everywhere

By following these practices, you'll create logo carousels that are smooth, accessible, responsive, and easy to maintain. For professional web development services that incorporate these best practices, explore our web development expertise.

Frequently Asked Questions

Ready to Build High-Performance Websites?

We create custom websites with modern technologies, optimal performance, and SEO best practices built in from the start.