Live Demo / Download
在本教程中,我们将向您展示如何仅使用CSS创建一个凉爽的无限水平动画。这种效果可用于显示各种事物,在这篇文章中,我们将专注于构建徽标旋转木制,使用尾风CSS类从右到左滚动。
最好的部分是您可以简单地将代码复制并粘贴到您的HTML页面中,而无需任何自定义CSS。
作为我们开始之前的最后一件事,如果您有兴趣在实际情况下看到无限的水平滚动,请查看我们的Dark Next.js landing page template或我们的recruitment website template。
让我们开始!
创建HTML结构
首先,让我们使用无序的列表为我们的徽标轮播建立一个简单的结构。
<div class="w-full inline-flex flex-nowrap">
<ul class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none">
<li>
<img src="./facebook.svg" alt="Facebook" />
</li>
<li>
<img src="./disney.svg" alt="Disney" />
</li>
<li>
<img src="./airbnb.svg" alt="Airbnb" />
</li>
<li>
<img src="./apple.svg" alt="Apple" />
</li>
<li>
<img src="./spark.svg" alt="Spark" />
</li>
<li>
<img src="./samsung.svg" alt="Samsung" />
</li>
<li>
<img src="./quora.svg" alt="Quora" />
</li>
<li>
<img src="./sass.svg" alt="Sass" />
</li>
</ul>
</div>
每个列表项目将代表公司的徽标,我们将alt属性添加到每个图像中以确保可访问性。
ul
元素具有flex
和items-center
的类
此外,我们使用了一些任意的尾风CSS变体来优化布局:
-
[&_li]:mx-8
向每个列表项目添加了32px的水平余量 -
[&_img]:max-w-none
删除默认的100%最大宽度应用于图像,即使在较小的屏幕上,也可以保留其原始尺寸
定义动画
定义动画很简单。我们需要做的就是将ul
元素从0转换为-100%。但是,Tailwind CSS不提供此特定的动画,因此我们会在我们的tailwind.config
对象中定义它。
通常,您在项目的根目录中有一个tailwind.config.js
文件。但是,由于我们使用了尾风CDN,因此我们将在HTML文件中的script
标签中定义tailwind.config
对象。
tailwind.config = {
theme: {
extend: {
animation: {
'infinite-scroll': 'infinite-scroll 25s linear infinite',
},
keyframes: {
'infinite-scroll': {
from: { transform: 'translateX(0)' },
to: { transform: 'translateX(-100%)' },
}
}
},
},
}
我们将动画命名为infinite-scroll
,它是线性的,无限的,持续25秒。我们还指定了动画的关键框架,以从0到-100%。
使用此动画就像将类animate-infinite-scroll
添加到您要翻译的元素一样容易。在我们的情况下,这就是ul
元素。
制作动画循环
现在,如果您预览页面,您会发现动画就像魅力一样!但是,当ul
元素到达-100%
,it suddenly jumps back to 0
时,有一个微小的打ic,打破了无缝的流程。
为了避免这种情况,我们将重复UL元素并立即将其放置在现有的元素之后。这样,当动画到达-100%
时,重复的元素接管了,确保动画继续而不会受到任何干扰。
我们知道html中的冗余元素是不可用的,因此,就目前而言,让我们将aria-hidden="true"
属性添加到重复的元素中,使屏幕阅读器看不见。后来,我们将使用一些JavaScript动态创建重复元素。
<div class="w-full inline-flex flex-nowrap">
<ul class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none animate-infinite-scroll">
<li>
<img src="./facebook.svg" alt="Facebook" />
</li>
<li>
<img src="./disney.svg" alt="Disney" />
</li>
<li>
<img src="./airbnb.svg" alt="Airbnb" />
</li>
<li>
<img src="./apple.svg" alt="Apple" />
</li>
<li>
<img src="./spark.svg" alt="Spark" />
</li>
<li>
<img src="./samsung.svg" alt="Samsung" />
</li>
<li>
<img src="./quora.svg" alt="Quora" />
</li>
<li>
<img src="./sass.svg" alt="Sass" />
</li>
</ul>
<ul class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none animate-infinite-scroll" aria-hidden="true">
<li>
<img src="./facebook.svg" alt="Facebook" />
</li>
<li>
<img src="./disney.svg" alt="Disney" />
</li>
<li>
<img src="./airbnb.svg" alt="Airbnb" />
</li>
<li>
<img src="./apple.svg" alt="Apple" />
</li>
<li>
<img src="./spark.svg" alt="Spark" />
</li>
<li>
<img src="./samsung.svg" alt="Samsung" />
</li>
<li>
<img src="./quora.svg" alt="Quora" />
</li>
<li>
<img src="./sass.svg" alt="Sass" />
</li>
</ul>
</div>
瞧!动画现在是无缝且永无止境的!如果您发现速度太慢或太快以至于无法获得口味,请继续调整tailwind.config.js
文件中的动画持续时间。
创建梯度面膜
即使我们为容器设定了最大宽度,但动画会有些野性,并延伸到边缘超出整个页面。这完全很好,但是如果您想将物品放在容器中,我们绝对需要一个渐变面膜。
只需在包含无序列表的元素中添加两个类:
-
overflow-hidden
,它隐藏了延伸超出容器边界的任何东西 -
[mask-image:_linear-gradient(to_right,transparent_0,_black_128px,_black_calc(100%-128px),transparent_100%)]
,在容器边缘定义梯度面具,从透明到黑色
<div class="w-full inline-flex flex-nowrap overflow-hidden [mask-image:_linear-gradient(to_right,transparent_0,_black_128px,_black_calc(100%-200px),transparent_100%)]">
<ul class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none animate-infinite-scroll">
<!-- ... -->
</ul>
<ul class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none animate-infinite-scroll" aria-hidden="true">
<!-- ... -->
</ul>
</div>
使用一些JavaScript克隆列表
好吧,如前所述,现在我们将看到如何使用Alpine.js轻松地创建重复元素以使代码更清洁,更可读。
这是我们要做的:
- 从HTML删除重复的列表
- 定义带有空对象的
x-data
指令 - 在包含要重复的列表的元素中添加一个
x-ref
属性,因此我们可以在Alpine.js 中参考它。
- 在页面加载时,用函数来定义
x-init
指令
<div
x-data="{}"
x-init="$nextTick(() => {
let ul = $refs.logos;
ul.insertAdjacentHTML('afterend', ul.outerHTML);
ul.nextSibling.setAttribute('aria-hidden', 'true');
})"
class="w-full inline-flex flex-nowrap overflow-hidden [mask-image:_linear-gradient(to_right,transparent_0,_black_128px,_black_calc(100%-128px),transparent_100%)]"
>
<ul x-ref="logos" class="flex items-center justify-center md:justify-start [&_li]:mx-8 [&_img]:max-w-none animate-infinite-scroll">
<li>
<img src="./facebook.svg" alt="Facebook" />
</li>
<li>
<img src="./disney.svg" alt="Disney" />
</li>
<li>
<img src="./airbnb.svg" alt="Airbnb" />
</li>
<li>
<img src="./apple.svg" alt="Apple" />
</li>
<li>
<img src="./spark.svg" alt="Spark" />
</li>
<li>
<img src="./samsung.svg" alt="Samsung" />
</li>
<li>
<img src="./quora.svg" alt="Quora" />
</li>
<li>
<img src="./sass.svg" alt="Sass" />
</li>
</ul>
</div>
x-init
中定义的函数只需复制ul
元素并立即插入它,将aria-hidden
属性添加到重复的元素中。
结论
至于所有教程,我们还提供了Next.js和Vue的组件,因此您可以轻松地将此动画集成到您喜欢的框架中。
如果您渴望获得更多指南和提示,我们邀请您查看我们的Tailwind CSS tutorials部分或我们的Tailwind CSS templates画廊,如果您需要下一个项目的起点。