How to create silky smooth marquees on the web 🎉

In this post, I would like to share my recent study on how to implement marquee effect by reverse-engineering couple of real-world application from Vercel and Apple products. Stay tuned and read on guys 😎

Previously, I concluded my thoughts on scalable React application. One of my inspiration was the Storefront demo created by the team at Vercel which is completely open source. I really like the way they organize their code and how well-architected the whole application is. Among all the things that amazed me, the one below struck me the most and I didn't even know what it's called back then 😅

I started looking into their source code on how it's implemented. As it's turned out to be ridiculously simple thanks to the power of OSS - react-fast-marquee is the hero this time. As said by its description

A lightweight React component that utilizes the power of CSS animations to create silky smooth marquees.

It's really is that simple since the author achieved that by simply duplicate the children passed in from parent component in React (it's called slot in Vue) and put them inside overflow-hidden container. Then he initializes a simple CSS infinitive keyframe loop for these two to slide over by updating x position overtime via transform API - it's one of the ways to achieve high performance animation in the web

The key to understand how things work beautifully is as we start sliding the first item toward any directions. It will ideally pass the boundary of overflow-hidden container and leave the blank from its initial position. This is where the cloned item comes into play as it will follow right after the first item to cover the blank space left. Once the first item reach its 100% translateX, two items will switch back right away to its initial position and start repeating. It creates circle effect but in reality, this is how it's done 😎

I started using react-fast-marquee in some of my projects until I hit the bottleneck of CSS animation where it could get us go extra miles due to its limited API. It only supports running or paused state of transform animation. Yet we want something slow-down on hover which is inspired by Apple Arcade website

I started googling around, the best bet would be this answer from Stackoverflow on how to apply some physic over the container to makes it feel like running slower. It seems quite complicated and yet not effective and few gotchas as mentioned in the post. I really wanted something like Apple have in their website. Since there is nothing available from the Internet so that I have to do it the hard way. I opened up the dev tool and investigate on how Apple does it. Once again, it's simple yet not simpler. They apply similar technique used by library like react-fast-marque except they control things with JavaScript instead of CSS animation. I pretty much got an idea on how to do it and started prototyping them quickly in an hour or so. The result was really satisfying, you guys can play around with it over here. I don't know how Apple team does it specifically, I am betting on requestAnimationFrame API to avoid blocking rendering to achieve 60 FPS 😆

The source code is completely open, please feel free to head over to see how I achieve the demo above 😎 - https://github.com/willnguyen1312/vue-marquee

There you have it guys, my story on how I discovered simple yet effective technique to achieve marquee effect on the web. I chose Vue for demo purpose but the technique can be applied across frameworks 😊 This post is written on the last day of 2021. If you happen to read this, I wish you well and happy for the next year 2022 to come 🎉

❤️❤️❤️ Be well, Be happy ❤️❤️❤️