Infinite marquee animation with React and CSS
I saw this effect on the Next.js website and in a few others now and to be honest, I think it looks pretty cool, so in this post we are gonna try to replicate the effect using React and pure CSS.
In case you still don't know what I'm talking about, this is how the slider looks like
Example on Next.js website_
The effect is really simple and it consists on an automatic scroll moving from right to left on an infinite loop.
We are gonna try to make the component as reusable and flexible as possible so you can pass whatever you wants to it. Images, texts, cards, anything!
But first, let's start with the basic markup. The easiest way to achieve this effect is by duplicating the content.
Now we add some base css.
We are gonna use CSS animatons for this. I wrote a post on how to improve performance in CSS animations if you want to take a look at it as well. It's kinda cool.
Let's add the keyframes for moving the content from right to left.
Now we have the base code. We have a slider which is moving our content on an infinite loop from right to left. But we can go a bit further and add some options to customize a few parameters of component. Let's add a few more things.
Time control
We can expose a way to adjust the time duration of the animations. If you're using some CSS-in-JS library might be easier passing the prop down to the styled component but in our example we are gonna use inline-styling to achieve this.
Other options – and maybe a better one – could be calculate the time based on the number of children we're passing down. This would look like this.
Starting position
On the Next.js example we can see there're two parallels sliders and each of them has a different starting position.
Now, we are gonna use the left
property inside the sx
objet that is used on both of the children
containers, the original and the replicated.
And that's it.
Usage
This is how our final component API will look like
The item component could be anything and we can adjust the styles directly. If you want to modify the gap between the elements you can do it by adjusting the margin-right
property of each of the items or adjusting the default value inside the .content > *
selector on the styles.