Software Tech

Creating a Sliding Text Animation with Tailwind CSS

Live Demo / Download In this tutorial, we'll learn how to create a sliding text animation using only Tailwind

Creating a Sliding Text Animation with Tailwind CSS

Live Demo / Download

In this tutorial, we'll learn how to create sliding text animation using only Tailwind CSS. The animation will display a word sliding from the bottom to the top, replacing the previous word. This effect is especially helpful when you want to alternate multiple words in a sentence (similar to a carousel) and keep the overall density of text compact. You've probably seen this effect used a lot for headlines, but the use is not limited to them, and you can try it out in any title or even in paragraphs.

part of this tutorial? We will achieve all this using only Tailwind CSS—no need to write a single line of JavaScript!

Are you ready?

Let's get started!

Creating a new with Tailwind CDN

For this , we'll utilize the Tailwind CSS CDN. While it might not be the best approach for real projects, it's perfect for a tutorial like this. The CDN lets us use Tailwind directly in the browser, without any installation or configuration hassles. Additionally, we will be able to customize Tailwind's configuration directly in a script .

Let's start by creating a new HTML file and setting up the structure to host our carousel of words:


lang=“en”>

charset=“utf-8”>
Rotating Words Animation
name=“viewport” content=“width=device-width,initial-scale=1”>
rel=“preconnect” href=“https://fonts.googleapis.com”>
rel=“preconnect” href=“https://fonts.gstatic.com” crossorigin>
href=“https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap” rel=“stylesheet”>
src=“https://cdn.tailwindcss.com”

tailwind.config = {
theme: {
extend: {
fontFamily: {
inter: [Inter, sans-serif],
},
},
},
};


class=“relative -inter antialiased”>
class=“relative min-h-screen flex flex-col justify-center bg-slate-900 overflow-hidden”>
class=“w-full max-w-6xl -auto px-4 md:px-6 py-24”>
class=“text-center”>





Creating the

Now, let's replace the comment with the HTML code for the headline:

class=“font-extrabold text-3xl md:text-4xl [text-wrap:balance] bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 to-50% to-slate-200”>Trusted by the most innovative minds in class=“text-indigo-500 inline-flex flex-col”>
class=“block text-left leading-tight [&_li]:block”>
Finance
Tech
AI
Crypto
eCommerce

We've created a line of text accompanied by an unordered list of words that we want to rotate. Notice how the first word “Finance” lines up perfectly with the white text, while the others wait separate lines.

But, before we dive into showing one word at a time from the list, let's take a moment to define the animation itself. Once the animation is all up, we can move on to taking care of how we hide the other words in the list.

Animating the word list block

OK. We have a list of words, and we want them to scroll up at regular intervals. To achieve this, we'll use the CSS animation property. But before we do that, we'll duplicate the first element and append it at the end. This ensures that the scrolling animation occurs seamlessly, without any disruptive interruptions. Let's modify the list like this:

class=“font-extrabold text-3xl md:text-4xl [text-wrap:balance] bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 to-50% to-slate-200”>Trusted by the most innovative minds in class=“text-indigo-500 inline-flex flex-col”>
class=“block text-left leading-tight [&_li]:block”>
Finance
Tech
AI
Crypto
eCommerce
aria-hidden=“true”>Finance

Since the duplicated element is only needed for the animation, we have used the attribute aria-hidden=”true” to make it accessible but not visible to screen readers.

Perfect! With a list of 6 elements, we need an animation with 6 steps. Let's define the translation values for each step. To calculate them, we'll use the formula 100% / number of elements. In our case, 100% / 6 = 16.6666666667%. So, the translation values will be:

0%
16.66%
33.33%
50%
66.66%
83.33%

Now we need to identify the appropriate keyframe-selectors. These are crucial points of the animation to which we'll assign the translation values we calculated earlier. Through some experimentation, we found that for a good result, each word should remain visible for 4/5 of the time and translate for 1/5 of the time.

So, to calculate the keyframe-selectors, follow these steps:

Divide 100% by 5 (the actual number of elements in the list): 100% / 5 = 20%

Calculate the transition time, defined as 1/5: 20% / 5 = 4%

Calculate the dwell time, defined as 4/5: 20% / 5 * 4 = 16%

Now, we have all the elements to define our animation. Let's define our animation with @keyframes:

‘0%, 16%': {
transform: ‘translateY(0%)',
},
‘20%, 36%': {
transform: ‘translateY(-16.66%)',
},
‘40%, 56%': {
transform: ‘translateY(-33.33%)',
},
‘60%, 76%': {
transform: ‘translateY(-50%)',
},
‘80%, 96%': {
transform: ‘translateY(-66.66%)',
},
‘100%': {
transform: ‘translateY(-83.33%)',
},

The whole animation will last for 12.5 seconds (2.5 seconds per word), and here's how the transitions will work:

From 0 to 2 seconds, the word Finance is visible
From 2 to 2.5 seconds, the transition from Finance to Tech takes place
From 2.5 to 4.5 seconds, the word Tech is visible
From 4.5 to 5 seconds, the transition from Tech to AI takes place
From 5 to 7 seconds, the word AI is visible
From 7 to 7.5 seconds, the transition from AI to Crypto takes place
From 7.5 to 9.5 seconds, the word Crypto is visible
From 9.5 to 10 seconds, the transition from Crypto to eCommerce takes place
From 10 to 12 seconds, the word eCommerce is visible
From 12 to 12.5 seconds, the transition from eCommerce to Finance (the one added to the end of the list) takes place

After the last transition, the last word in the list is replaced by the first word (without any transition), and the animation starts again from the beginning, creating a of continuity!

Debugging the animation

Now that we've defined all the animation values, it's time to incorporate them into the tailwind.config object:

tailwind.config = {
theme: {
extend: {
fontFamily: {
inter: [Inter, sans-serif],
},
animation: {
text-slide: text-slide 12.5s cubic-bezier(0.83, 0, 0.17, 1) infinite,
},
keyframes: {
text-slide: {
0%, 16%: {
transform: translateY(0%),
},
20%, 36%: {
transform: translateY(-16.66%),
},
40%, 56%: {
transform: translateY(-33.33%),
},
60%, 76%: {
transform: translateY(-50%),
},
80%, 96%: {
transform: translateY(-66.66%),
},
100%: {
transform: translateY(-83.33%),
},
},
},
},
},
};

In addition to setting the duration to 12.5 seconds, we've also defined a cubic-bezier curve to make the animation smoother and more natural.

Now, to see it in action, all we need to do is add the class animate-text-slide to our ul element:

class=“font-extrabold text-3xl md:text-4xl [text-wrap:balance] bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 to-50% to-slate-200”>Trusted by the most innovative minds in class=“text-indigo-500 inline-flex flex-col”>
class=“block animate-text-slide text-left leading-tight [&_li]:block”>
Finance
Tech
AI
Crypto
eCommerce
aria-hidden=“true”>Finance

Displaying one word at a time

Here we are at the last step, we will create a kind of mask to display only one word at a time, namely the one currently aligned with the white text.

To do this, we need to set a fixed height to the element containing the unordered list, equal to the line-height of the elements in the list. Then, we need to set the overflow of the element to hidden to hide the words that are not aligned with the white text.

So, Let's add these classes to the element:

h-[calc(theme(fontSize.3xl)*theme(lineHeight.tight))] sets the correct height on smaller screens
md:h-[calc(theme(fontSize.4xl)*theme(lineHeight.tight))] sets the correct height from medium screens onwards
overflow-hidden hides everything that exceeds

Let's unveil the final result:

class=“font-extrabold text-3xl md:text-4xl [text-wrap:balance] bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 to-50% to-slate-200”>Trusted by the most innovative minds in class=“text-indigo-500 inline-flex flex-col h-[calc(theme(fontSize.3xl)*theme(lineHeight.tight))] md:h-[calc(theme(fontSize.4xl)*theme(lineHeight.tight))] overflow-hidden”>
class=“block animate-text-slide-5 text-left leading-tight [&_li]:block”>
Finance
Tech
AI
Crypto
eCommerce
aria-hidden=“true”>Finance

The animation works like a charm, but what if you want to add or remove words from the list? 🤔

Changing the number of words in the carousel

Now, we have good news and bad news! 😄

Let's start with the bad, just to get it out of the way. If you ever need to adjust the animation for a different number of words, you'll have to recalculate all the animation values.

The good news is that we've done it for you, defining animations for word counts ranging from 2 to 8 words! You can find them all in the tailwind.config.js object:

animation: {
‘text-slide-2': ‘text-slide-2 5s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-3': ‘text-slide-3 7.5s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-4': ‘text-slide-4 10s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-5': ‘text-slide-5 12.5s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-6': ‘text-slide-6 15s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-7': ‘text-slide-7 17.5s cubic-bezier(0.83, 0, 0.17, 1) infinite',
‘text-slide-8': ‘text-slide-8 20s cubic-bezier(0.83, 0, 0.17, 1) infinite',
},
keyframes: {
‘text-slide-2': {
‘0%, 40%': {
transform: ‘translateY(0%)',
},
‘50%, 90%': {
transform: ‘translateY(-33.33%)',
},
‘100%': {
transform: ‘translateY(-66.66%)',
},
},
‘text-slide-3': {
‘0%, 26.66%': {
transform: ‘translateY(0%)',
},
‘33.33%, 60%': {
transform: ‘translateY(-25%)',
},
‘66.66%, 93.33%': {
transform: ‘translateY(-50%)',
},
‘100%': {
transform: ‘translateY(-75%)',
},
},
‘text-slide-4': {
‘0%, 20%': {
transform: ‘translateY(0%)',
},
‘25%, 45%': {
transform: ‘translateY(-20%)',
},
‘50%, 70%': {
transform: ‘translateY(-40%)',
},
‘75%, 95%': {
transform: ‘translateY(-60%)',
},
‘100%': {
transform: ‘translateY(-80%)',
},
},
‘text-slide-5': {
‘0%, 16%': {
transform: ‘translateY(0%)',
},
‘20%, 36%': {
transform: ‘translateY(-16.66%)',
},
‘40%, 56%': {
transform: ‘translateY(-33.33%)',
},
‘60%, 76%': {
transform: ‘translateY(-50%)',
},
‘80%, 96%': {
transform: ‘translateY(-66.66%)',
},
‘100%': {
transform: ‘translateY(-83.33%)',
},
},
‘text-slide-6': {
‘0%, 13.33%': {
transform: ‘translateY(0%)',
},
‘16.66%, 30%': {
transform: ‘translateY(-14.28%)',
},
‘33.33%, 46.66%': {
transform: ‘translateY(-28.57%)',
},
‘50%, 63.33%': {
transform: ‘translateY(-42.85%)',
},
‘66.66%, 80%': {
transform: ‘translateY(-57.14%)',
},
‘83.33%, 96.66%': {
transform: ‘translateY(-71.42%)',
},
‘100%': {
transform: ‘translateY(-85.71%)',
},
},
‘text-slide-7': {
‘0%, 11.43%': {
transform: ‘translateY(0%)',
},
‘14.28%, 25.71%': {
transform: ‘translateY(-12.5%)',
},
‘28.57%, 40%': {
transform: ‘translateY(-25%)',
},
‘42.85%, 54.28%': {
transform: ‘translateY(-37.5%)',
},
‘57.14%, 68.57%': {
transform: ‘translateY(-50%)',
},
‘71.42%, 82.85%': {
transform: ‘translateY(-62.5%)',
},
‘85.71%, 97.14%': {
transform: ‘translateY(-75%)',
},
‘100%': {
transform: ‘translateY(-87.5%)',
},
},
‘text-slide-8': {
‘0%, 10%': {
transform: ‘translateY(0%)',
},
‘12.5%, 22.5%': {
transform: ‘translateY(-11.11%)',
},
‘25%, 35%': {
transform: ‘translateY(-22.22%)',
},
‘37.5%, 47.5%': {
transform: ‘translateY(-33.33%)',
},
‘50%, 60%': {
transform: ‘translateY(-44.44%)',
},
‘62.5%, 72.5%': {
transform: ‘translateY(-55.55%)',
},
‘75%, 85%': {
transform: ‘translateY(-66.66%)',
},
‘87.5%, 97.5%': {
transform: ‘translateY(-77.77%)',
},
‘100%': {
transform: ‘translateY(-88.88%)',
},
}
},

class=“font-extrabold text-3xl md:text-4xl [text-wrap:balance] bg-clip-text text-transparent bg-gradient-to-r from-slate-200/60 to-50% to-slate-200”>Trusted by the most innovative minds in class=“text-indigo-500 inline-flex flex-col h-[calc(theme(fontSize.3xl)*theme(lineHeight.tight))] md:h-[calc(theme(fontSize.4xl)*theme(lineHeight.tight))] overflow-hidden”>
class=“block animate-text-slide-5 text-left leading-tight [&_li]:block”>
Finance
Tech
aria-hidden=“true”>Finance

Conclusions

We hope this tutorial will give your headlines/sentences a bit of character, and if you're interested in learning more about similar tips and tricks, check out our section of Tailwind CSS tutorials.

About Author

Cruip

Leave a Reply

SOFAIO BLOG We would like to show you notifications for the latest news and updates.
Dismiss
Allow Notifications