Live Demo / Download
在本教程中,我们将学习如何仅使用尾风CSS创建滑动文本动画。动画将显示一个从底部到顶部滑动的单词,以取代上一个单词。当您想在句子中交替多个单词(类似于轮播)并保持文本紧凑的整体密度时,这种效果特别有用。您可能会看到这种效果在头条新闻中使用了很多,但是使用不限于它们,并且可以在任何标题甚至段落中尝试一下。
本教程中最好的部分?我们将仅使用tailwind CSS 来实现这一切 - 不需要编写一行JavaScript!
你准备好了吗?
让我们开始!
用尾风CDN创建新文档
在此实验中,我们将利用尾风CSS CDN。虽然它可能不是真正项目的最佳方法,但对于这样的教程来说,它是完美的选择。 CDN使我们可以直接在浏览器中使用尾风,而无需任何安装或配置麻烦。此外,我们将能够直接在script
标签中自定义尾风的配置。
让我们开始创建一个新的HTML文件并设置结构以托管我们的单词旋转木马:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Rotating Words Animation</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
inter: ['Inter', 'sans-serif'],
},
},
},
};
</script>
</head>
<body class="relative font-inter antialiased">
<main class="relative min-h-screen flex flex-col justify-center bg-slate-900 overflow-hidden">
<div class="w-full max-w-6xl mx-auto px-4 md:px-6 py-24">
<div class="text-center">
<!-- Rotating words animation -->
</div>
</div>
</main>
</body>
</html>
创建标题
现在,让我们用标题的HTML代码替换评论:
<div 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 <span class="text-indigo-500 inline-flex flex-col">
<ul class="block text-left leading-tight [&_li]:block">
<li>Finance</li>
<li>Tech</li>
<li>AI</li>
<li>Crypto</li>
<li>eCommerce</li>
</ul>
</span></div>
我们创建了一系列文本,并伴随着我们想要旋转的无序列表。请注意,第一个单词如何与白色文本完美地排列在一起,而其他单词则在单独的行上等待。
但是,在我们深入研究一个单词之前,让我们花一点时间来定义动画本身。一旦建立了动画,我们就可以继续照顾我们如何隐藏列表中的其他单词。
动画单词列表块
好的。我们有一个单词列表,我们希望他们定期滚动。为此,我们将使用 css动画属性。但是在这样做之前,我们将重复第一个元素并在最后附加。这样可以确保滚动动画无缝地发生,而不会造成任何破坏性中断。让我们修改这样的列表:
<div 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 <span class="text-indigo-500 inline-flex flex-col">
<ul class="block text-left leading-tight [&_li]:block">
<li>Finance</li>
<li>Tech</li>
<li>AI</li>
<li>Crypto</li>
<li>eCommerce</li>
<li aria-hidden="true">Finance</li>
</ul>
</span></div>
由于动画仅需要重复的元素,因此我们使用属性aria-hidden="true"
使其可访问,但对于屏幕读取器而言不可见。
完美!有了6个元素的列表,我们需要一个具有 6个步骤的动画。让我们定义每个步骤的翻译值。为了计算它们,我们将使用公式100% / number of elements
。在我们的情况下,100% / 6 = 16.6666666667%
。因此,翻译值将是:
- 0%
- 16.66%
- 33.33%
- 50%
- 66.66%
- 83.33%
现在我们需要确定适当的keyframe-selectors
。这些是动画的关键点,我们将分配了我们之前计算的翻译值。通过一些实验,我们发现为了取得良好的结果,每个单词的时间应保持4/5,并在当时的时间为1/5。
so,要计算keyframe-selectors
,请按照以下步骤:
- 将100%除以5(列表中的实际元素数):
100% / 5 = 20%
- 计算过渡时间,定义为1/5:
20% / 5 = 4%
- 计算定义为4/5:
20% / 5 * 4 = 16%
的停留时间
现在,我们有所有元素来定义动画。让我们用@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%)',
},
整个动画将持续使用12.5
秒(每个单词的2.5
秒),在这里,过渡将如何工作:
- 从0到2秒,单词 finance 可见
- 从2到2.5秒,从金融> 到 Tech 进行过渡
- 从2.5到4.5秒,一词 Tech 可见
- 从4.5秒到5秒,从 Tech 到 ai 进行过渡
- 从5到7秒,可见 ai 一词
- 从7到7.5秒,从 ai 到加密>的过渡发生
- 从7.5到9.5秒,单词加密>可见
- 从9.5到10秒,从加密>到电子商务的过渡发生
- 从10到12秒,可见电子商务
- 从12到12.5秒,从电子商务过渡到财务(添加到列表末尾的一个)进行了
最后一个过渡后,列表中的最后一个单词被第一个单词替换(没有任何过渡),动画从一开始就再次开始,创造了一种连续性!
调试动画
现在我们定义了所有动画值,现在该将它们纳入tailwind.config
对象了:
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%)',
},
},
},
},
},
};
除了将持续时间设置为12.5
秒之外,我们还定义了cubic-bezier
曲线以使动画更光滑,更自然。
现在,要在行动中看到它,我们需要做的就是将animate-text-slide
类添加到我们的ul
元素:
<div 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 <span class="text-indigo-500 inline-flex flex-col">
<ul class="block animate-text-slide text-left leading-tight [&_li]:block">
<li>Finance</li>
<li>Tech</li>
<li>AI</li>
<li>Crypto</li>
<li>eCommerce</li>
<li aria-hidden="true">Finance</li>
</ul>
</span></div>
一次显示一个字
在这里,我们处于最后一步,我们将创建一种掩码一次仅显示一个单词,即当前与白色文本对齐的掩码。
要这样做,我们需要将固定高度设置为包含列表的元素,等于列表中元素的线路高度。然后,我们需要将元素的溢出设置为hidden
,以隐藏与白色文本不符的单词。
所以,让我们将这些类添加到元素中:
-
h-[calc(theme(fontSize.3xl)*theme(lineHeight.tight))]
设置了较小屏幕上的正确高度 -
md:h-[calc(theme(fontSize.4xl)*theme(lineHeight.tight))]
设置了从中屏幕开始的正确高度 -
overflow-hidden
隐藏了超过一切 的一切
让最终结果公开:
<div 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 <span 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">
<ul class="block animate-text-slide-5 text-left leading-tight [&_li]:block">
<li>Finance</li>
<li>Tech</li>
<li>AI</li>
<li>Crypto</li>
<li>eCommerce</li>
<li aria-hidden="true">Finance</li>
</ul>
</span></div>
动画就像魅力一样,但是如果您想从列表中添加或删除单词,该怎么办? ðρ
改变轮播中的单词数量
现在,我们有个好消息和坏消息! ð
让我们从坏处开始,只是为了摆脱困境。如果您需要为不同数量的单词调整动画,则必须重新计算所有动画值。
好消息是,我们为您做了,定义了单词计数的动画,范围为2到8个单词!您可以在tailwind.config.js
对象中找到所有内容:
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%)',
},
}
},
因此,如果您的列表仅包含两个单词,则只需在<ul>
元素上使用animation-text-slide-2
类即可。例如:
<div 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 <span 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">
<ul class="block animate-text-slide-5 text-left leading-tight [&_li]:block">
<li>Finance</li>
<li>Tech</li>
<li aria-hidden="true">Finance</li>
</ul>
</span></div>
结论
我们希望本教程能为您的头条/句子提供一些角色,如果您有兴趣了解有关类似技巧和技巧的更多信息,请查看我们的Tailwind CSS tutorials1111。