本文关注如何在一个网页中使用纯 CSS 实现文字轮播和图片轮播。文字轮播适用于做全站广播,图片轮播适用于在固定区域内循环展示一组图片,它们两者都可以使用 CSS 动画来实现。
文字轮播即是在水平方向或垂直方向无限循环展示一组文字。
一个垂直方向的文字轮播效果如下:
其完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Text Carousel</title>
<style>
:root {
/* 轮播的条数,可以覆盖 */
--s: 6;
/* 单个条目的高度 */
--h: 36;
/* 单次动画的时长 */
--speed: 3s;
}
.container {
width: 200px;
height: calc(var(--h) * 1px);
line-height: calc(var(--h) * 1px);
border-radius: 4px;
border: 1px solid darkgray;
overflow: hidden;
}
ul {
margin-top: auto;
margin-bottom: auto;
animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
white-space: nowrap;
list-style: none;
animation: liMove calc(var(--speed)) infinite;
}
@keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, calc(var(--s) * var(--h) * -1px));
}
}
@keyframes liMove {
0% {
transform: translate(0, 0);
}
80%,
100% {
transform: translate(0, calc(var(--h) * -1px));
}
}
</style>
</head>
<body>
<div class="container">
<ul style="--s: 4">
<li>Text Carousel 1</li>
<li>Text Carousel 2</li>
<li>Text Carousel 3</li>
<li>Text Carousel 4</li>
<!-- 将第一条数据补到末尾 -->
<li>Text Carousel 1</li>
</ul>
</div>
</body>
</html>
可以看到,逐帧动画可以实现整体的轮播效果。
ul {
animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
@keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, calc(var(--s) * var(--h) * -1px));
}
}
补间动画可以将状态的切换显得更平滑。
ul li {
animation: liMove calc(var(--speed)) infinite;
}
@keyframes liMove {
0% {
transform: translate(0, 0);
}
80%,
100% {
transform: translate(0, calc(var(--h) * -1px));
}
}
HTML 结构中最后补一条头部数据可以将条目循环的平滑与连续。
<ul style="--s: 4">
<!-- ... -->
<!-- 将第一条数据补到末尾 -->
<li>Text Carousel 1</li>
</ul>
文字可以借助 CSS 动画实现轮播,图片同样可以。
上面的文字轮播是在垂直方向进行的,接下来我们看一下如何在水平方向将图片进行循环轮播。
一个水平方向的图片轮播效果如下:
其完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Carousel</title>
<style>
:root {
/* 轮播的条数,可以覆盖 */
--s: 6;
/* 单个条目的宽度 */
--w: 360;
/* 单次动画的时长 */
--speed: 3s;
}
.container {
margin: auto;
width: calc(var(--w) * 1px);
height: 280px;
line-height: 280px;
border-radius: 4px;
border: 1px solid darkgray;
overflow: hidden;
}
ul {
margin: 0;
padding: 0;
display: flex;
flex-wrap: nowrap;
animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
flex-shrink: 0;
width: 100%;
height: 100%;
white-space: nowrap;
list-style: none;
animation: liMove calc(var(--speed)) infinite;
}
ul li img {
width: 100%;
height: 100%;
}
@keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(calc(var(--s) * var(--w) * -1px), 0);
}
}
@keyframes liMove {
0% {
transform: translate(0, 0);
}
80%,
100% {
transform: translate(calc(var(--w) * -1px), 0);
}
}
</style>
</head>
<body>
<div class="container">
<ul style="--s: 3">
<li><img src="https://leileiluoluo.github.io/static/samples/2024/image-carousel/images/image-carousel-1.png"></li>
<li><img src="https://leileiluoluo.github.io/static/samples/2024/image-carousel/images/image-carousel-2.png"></li>
<li><img src="https://leileiluoluo.github.io/static/samples/2024/image-carousel/images/image-carousel-3.png"></li>
<!-- 将第一条数据补到末尾 -->
<li><img src="https://leileiluoluo.github.io/static/samples/2024/image-carousel/images/image-carousel-1.png"></li>
</ul>
</div>
</body>
</html>
可以看到,上述图片轮播代码与前面文字轮播相似,不同的地方只在于 transform
由垂直移位改为了水平移位。
总结文字轮播与图片轮播的实现要点,主要有三点:
本文完整示例代码已托管至我的 GitHub,欢迎关注或 Fork。
参考资料
[1] SegmentFault:文字轮播与图片轮播?CSS 不在话下 - https://segmentfault.com/a/1190000041947673