← Back to blogYouTube Video

Published April 8, 2025

Landing Page Design Tutorial - NextJS & Tailwind (Travel Agency) - Part 5

Part 5 of 13 in Landing Page Design with Next.js & Tailwind

Can't play the video or having issues? Here's the direct link.

Summary

I build a horizontally scrolling, animated offers section in Next.js and Tailwind, starting from a reusable component and an offers array with text, link, and icon fields. I pull five icons from Compose Icons, render each offer as a link, and fix casing errors by converting icon exports to camelCase. The core trick is duplicating the offer list inside an overflow-hidden, no-wrap container and animating it with a CSS keyframe from translateX(0) to translateX(-100%) over 9 seconds, linear and infinite. I also pause the animation on hover using animation-play-state: paused, and land on a clean looping marquee that cuts off at the edges and reads well.

Key takeaways

  • Duplicate the offer list before animating a marquee; a single list will look cut off as it scrolls.
  • Define the slide animation in globals.css with keyframes from translateX(0) to translateX(-100%), then run it linear and infinite.
  • Tune marquee speed by duration: 5s felt too fast, and 9s was the right pace for this offers section.
  • Wrap the duplicated lists in a parent with overflow-hidden and whitespace-nowrap so the row stays on one line and clips cleanly.
  • Pause the marquee on hover with animation-play-state: paused on the animated elements.
  • Keep icon exports in camelCase to avoid JSX casing errors when importing them into components.

Description

Source code: https://github.com/hassanaziz0012/travel-buddy

Transcript

Auto-generated transcript
All right. Hello and welcome back. This has been there's been a lot of delays with this one, but this is what we've got so far. And this is what we're going to build. This is basically just a horizontal sliding animated offer section which basically will display a bunch of offers that we want to display here. Ignore the essential section below that, that's something we will build in a future episode. That's not for this one. So to get started, first we'll build a component for this. I'm just going to call this scrolling office of a better name. Here's our component. Now let's render this on the page. Now we're also going to create a list of offers up here and these are going to have a bunch of fields which will be text, link and an icon. We're going to give these three fields to each offer and then we're just going to duplicate this four or five times. Let's say five times. Now we need a bunch of icons for this and I'm just going to get all of these from compose icons. We'll take this one and put this in our icons.tsx file as always. And it seems we already have one with this name so yeah up there. So we need to rename this to something else. Let's just go with it plain too. We're gonna add the screen readers label as well and then get the next icon. Let's go with this one. Again same process just add this over here add the screen label. Let's look for the perfect icon. There a lot to look through but I think I go with this one Copy that and we add that here as well Now we're going to get this icon as well. And lastly we just need one final icon. go with this one okay with that we have all of the icons that we need so let's start adding our offers over here. I'm going to add the text and the icon for each offer and I'm just gonna keep the link empty because we don't actually need a link here. This is just like an example project so the link I'll just keep that empty and I'll fill up the text and the icons. So I import the icons and add one icon for each of these offers. Okay, now with all of that, we are ready to render these. So first, let's change this to a section and create another div inside and let's render the office in here. And of course add the key as well so we don't get some errors. let's make this a flexbox as well and add some gap. Now render the icon over here and add the text as well. I also make this a link which will open the offers link which again we kept empty but we could obviously add any link we want over there now up here let's also make this a flexbox as well and add some more gap over here we'll also give this section some background colors and some padding and also make text white Now let's see what we have so far and this is what we're working with right now. So there's a lot to do. First let's reduce the section padding and also increase the gap here. That's a bit better. make this text uppercase and also larger and bold and that's a lot more of what we want and let's also fix this issue while we're at it so to fix this just go to icons and change the casing to camel case for all of these variables I'm just going to use find and replace to do this quickly we just need to change the casing for each of these attributes to camel case and there we go okay now that error is also gone let's continue making these offers. I'll put all of these in a container for now just so it's a bit more organized and now the text is wrapping and we don't want that so I'm going to add another class here which will be text no wrap and that fixes the wrapping issue. I'll also add overflow hidden so it cuts off at the end here like so. Now we need to head over to globals.css and we actually need to add the sliding animation. Now I'm using Tailwind here so to do this let's just add a keyframes and I'll just call this horizontal scroll and what this will do is just go from transform translate X 0 to transform translate X minus 100% and that's our animation now let's also add animate horizontal scroll actually I I think I have a better name for this Let call it slide Animate slide and also change the name over here Now let add this animation We run it for five seconds and we also write linearly and infinite so it doesn ever end Now let remove this gap and add a padding over here and we have the same effect and that's fine. Now let's create an inline block element up here and move this entire thing up there. We'll remove the overflow hidden in the text no wrap classes and we'll duplicate this inline block element one more time. So we actually need two lists of offers as in a duplicate of the original list to animate this correctly otherwise it will just appear cut off and this is what it looks like now so let's move both of these inline block elements into the div and I'll add the overflow hidden and the text no wrap classes to this parent div and now we get this now we can actually add the animation and I'm just going to add the animate slide class here and now we have our animations working but this is a bit too fast so I'm going to go back to global CSS and I'm going to increase this to 7 seconds and it's just still too fast so let's try 8 seconds. Now let's go with 9 seconds and yeah let's just go with 9 seconds and that's good enough. Now we also want to pause this animation on hover and to do that let's use this custom property animation play state equals paused and let's also add this to the other elements where we're animating this and with that this animation will pause whenever we hover over the office and with that we are done with this section as you can see it powers it pauses when I hover over it and yeah that's all we needed to build for this section you you

Share this article

Hassan Aziz pointing up

Dude, you’re at the bottom of my landing page.

Just book a call already if you’re that interested.

You scrolled all the way here.