How to use CSS to create an infinite horizontal scrolling effect.
<?php
$logos = get_field('logos');
if( $logos ): ?>
<div class="marquee">
<div class="marquee__inner">
<?php foreach( $logos as $logo ) : ?>
<div class="marquee__item">
<?= wp_get_attachment_image( $logo, 'full' ); ?>
</div>
<?php endforeach; ?>
</div>
<?php /** Duplicate the marquee to create the illusion of an unending list of logos */ ?>
<div class="marquee__inner" aria-hidden="true">
<?php foreach( $logos as $logo ) : ?>
<div class="marquee__item">
<?= wp_get_attachment_image( $logo, 'full' ); ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
.marquee {
--gap: 8rem;
--speed: 40s;
display: flex;
align-items: center;
overflow: hidden;
position: relative;
gap: var(--gap);
&:hover {
.marquee__inner {
animation-play-state: paused; // <-- Optional: this will pause the animation when then marquee is hovered
}
}
}
.marquee__inner {
display: flex;
align-items: center;
gap: var(--gap);
animation: scroll-left var(--speed) linear infinite;
flex-shrink: 0;
}
.marquee__item {
flex: 0 0 auto; // <-- ensures the items don't shrink
max-width: 190px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
@keyframes scroll-left {
0% {
transform: translateX(0%);
}
100% {
transform: translateX(calc(-100% - var(--gap))); // <-- this will ensure a smooth transition instead of the marquee jerking back to place when then translate animation is complete
}
}
You will most likely need to tweak the code to fit your needs, but this should give you a solid starting point.