J.Whiting.

Creating a Marquee with Tailwind CSS

On a recent project, I was tasked with adding a marquee element to display a few key terms. This was required to be on an infinite loop.

Creating the Marquee

I managed to create something simple with just CSS and HTML. The first thing we need to do is get a collection of items that will be used in our Marquee.

<div class="overflow-x-hidden">
    <div class="py-12 animate-marquee whitespace-nowrap ">
        <span class="mx-4 text-4xl">Marquee Item 1</span>
        <span class="mx-4 text-4xl">Marquee Item 2</span>
        <span class="mx-4 text-4xl">Marquee Item 3</span>
        <span class="mx-4 text-4xl">Marquee Item 4</span>
        <span class="mx-4 text-4xl">Marquee Item 5</span>
    </div>
</div>
These items should always take up more space than the screen width otherwise there wouldn't be much point in turning them into a marquee.

Adding Animation

To get the element to move, we'll create an animation that moves the element from 0% (the default position) to -100% - ensuring the element moves off the screen until it reaches the end.

module.exports = {
  extend: {
    animation: {
      marquee: 'marquee 25s linear infinite',
    },
    keyframes: {
      marquee: {
        '0%': { transform: 'translateX(0%)' },
        '100%': { transform: 'translateX(-100%)' },
      }
    },
  }
}

View Demo

Looping the Marquee

Currently, there is a lot of white space that trails the last element until it gets to the edge of the screen and then jumps back to the first item.

We want our marquee to be smoother and look like it's repeating. To do this, we'll need to create a copy of the original marquee elements and add a slightly different animation to it.

Update our HTML

Let's add the second marquee and ensure it's spaced the same as the first one. We then set it as absolute so that we don't have an increase in parent element height. We also apply flex to the parent to ensure the elements sit nicely next to each other.

<div class="relative flex overflow-x-hidden">
  <div class="py-12 animate-marquee whitespace-nowrap">
    <span class="mx-4 text-4xl">Marquee Item 1</span>
    <span class="mx-4 text-4xl">Marquee Item 2</span>
    <span class="mx-4 text-4xl">Marquee Item 3</span>
    <span class="mx-4 text-4xl">Marquee Item 4</span>
    <span class="mx-4 text-4xl">Marquee Item 5</span>
  </div>

  <div class="absolute top-0 py-12 animate-marquee2 whitespace-nowrap">
    <span class="mx-4 text-4xl">Marquee Item 1</span>
    <span class="mx-4 text-4xl">Marquee Item 2</span>
    <span class="mx-4 text-4xl">Marquee Item 3</span>
    <span class="mx-4 text-4xl">Marquee Item 4</span>
    <span class="mx-4 text-4xl">Marquee Item 5</span>
  </div>
</div>

Update Tailwind

Then we can add the second animation for marquee2 to our tailwind.config.js.

module.exports = {
  extend: {
    animation: {
      marquee: 'marquee 25s linear infinite',
      marquee2: 'marquee2 25s linear infinite',
    },
    keyframes: {
      marquee: {
        '0%': { transform: 'translateX(0%)' },
        '100%': { transform: 'translateX(-100%)' },
      },
      marquee2: {
        '0%': { transform: 'translateX(100%)' },
        '100%': { transform: 'translateX(0%)' },
      },
    },
  }
}

Our animation for marquee2 is translating the second element from 100% to 0 at the same speed as the first element, so they will smoothly follow each other.

When the first element reaches the edge of the screen it will snap back to 0% and begin to be translated again. Due to our second element being at the same point there will be no visual interference to the end user.

Demo

You can view a demo of the final code over on the Tailwind CSS Play.

That's it, we're all done. I hope this article helps you.