大家好!我想分享一些使用 CSS 创建无限轮播的 CSS 技巧。让我们开始吧。
HTML:
此 HTML 代码使用 <ul>
图库创建了一个图像轮播图。每个 <li>
包含一张图片和一个用于动画排序的 '--timer'
变量。
<section>
<div class="carousel">
<ul class="gallery">
<li class="card" style="--timer: 1"><img src="img/1.jpg" alt=""></li>
<li class="card" style="--timer: 2"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 3"><img src="img/3.jpg" alt=""></li>
<li class="card" style="--timer: 4"><img src="img/4.jpg" alt=""></li>
<li class="card" style="--timer: 5"><img src="img/3.jpg" alt=""></li>
<li class="card" style="--timer: 6"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 7"><img src="img/1.jpg" alt=""></li>
<li class="card" style="--timer: 8"><img src="img/2.jpg" alt=""></li>
<li class="card" style="--timer: 9"><img src="img/3.jpg" alt=""></li>
</ul>
</div>
</section>
CSS:
--num
确定总图片数量。
--wd
确定 card
div 的宽度。
* {
margin: 0;
padding: 0;
}
:root {
--num: 9; /* 总图片数量 */
--wd: 130; /* card 元素的宽度 */
/* --gap: 20px; */
}
body {
background-color: #e4e7ee;
}
section {
width: clamp(480px, 80%, 90vw);
margin: 0 auto;
}
.carousel {
display: flex;
align-items: flex-start;
height: 100vh;
overflow: hidden;
/* 左右遮罩,类似渐变效果 */
mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent);
}
.carousel .gallery {
list-style-type: none;
display: flex;
align-items: center;
width: 100%;
height: 450px;
position: relative;
perspective: 40em;
}
.carousel .gallery .card {
width: 130px;
height: auto;
position: absolute;
transform-style: preserve-3d;
left: 100%;
animation: slide 9s linear infinite, scaleEffect 9s ease-in-out infinite;
animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1));
transition: transform 0.25s ease-in-out;
}
.carousel .gallery .card img {
width: 100%;
border-radius: 5px;
box-shadow: 0px 0px 16px #cecece;
/* 图片反射效果 */
-webkit-box-reflect: below 0px linear-gradient(to bottom, rgba(0, 0, 0, 0.0), rgba(0, 0, 0, 0.4));
}
CSS 动画解释:
.carousel .gallery .card
中使用的动画:
slide 9s linear infinite:
以 9 秒为周期,无限次重复,以恒定速度移动元素。
scaleEffect 9s ease-in-out infinite:
在 9 秒内应用缩放效果,平滑加速和减速,无限重复。
animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1)):
根据每个元素的 --timer
值计算延迟,确保同步过渡。
slide 动画解释:
@keyframes slide:
定义了一个使元素水平移动的动画。
from { left: 100%; }: 从最右侧位置开始。
to { left: calc(-1 * var(--wd) * 1px); }: 向左移动 --wd 像素,完全移出视口。
此动画通常用于滚动效果,如连续移动的轮播图或新闻头条。
@keyframes slide {
from {
left: 100%;
}
to {
left: calc(-1 * var(--wd)* 1px);
}
}
缩放效果动画解释:
@keyframes scaleEffect:
定义了一个带有灰度和图层效果的缩放动画。
0%, 25%, 75%, 100%: 元素保持正常缩放(scale(1)),堆叠顺序较低(z-index: 0),完全灰度(grayscale(1))。
50%: 元素放大到两倍大小(scale(2)),移到前景(z-index: 10),完全着色(grayscale(0))。
此动画创建了一个脉冲式缩放效果,使元素动态弹出并淡入。
@keyframes scaleEffect {
0%,
25%,
75%,
100% {
transform: scale(1);
z-index: 0;
filter: grayscale(1);
}
50% {
transform: scale(2);
z-index: 10;
filter: grayscale(0);
}
}
在下面的 GIF 中,你可以看到中心图像应用了缩放效果,以及两个相邻图像的中等缩放效果。
结果:
如果你只想让中心图像缩放,只需修改上面的 CSS 中的 scaleEffect
。
将 `@keyframes scaleEffect:` 中的 `0%, 25%, 75%, 100%` 替换为 `0%, 40%, 60%, 100%`。
然后你可以看到以下输出。
最后,让我们创建 3D 轮播图:
我已经在 .carousel .gallery
中设置了 perspective: 40em;
,在 .carousel .gallery .card
中设置了 transform-style: preserve-3d;
。现在,我们只需再次修改 scaleEffect
。
@keyframes scaleEffect {
0%, 25%, 75%, 100% {
transform: scale(1) rotateY(0deg);
z-index: 0;
filter: grayscale(1);
}
35% {
transform: scale(1.25) rotateY(-45deg);
z-index: 5;
filter: grayscale(1);
}
50% {
transform: scale(2) rotateY(0deg);
z-index: 10;
filter: grayscale(0);
}
65% {
transform: scale(1.25) rotateY(45deg);
z-index: 5;
filter: grayscale(1);
}
}
结果:
我们的 3D 轮播图 完成!不过,你仍然可以通过对 scaleEffect
进行微调来尝试不同的变换效果。
让我们创建 COVERFLOW:
@keyframes scaleEffect {
0%, 40%, 60%, 100% {
transform: scale(1) rotateY(-90deg);
z-index: 0;
filter: grayscale(1);
}
50% {
transform: scale(2) rotateY(0deg);
z-index: 10;
filter: grayscale(0);
}
}
COVERFLOW 结果:
将 coverflow 代码中的变换值从 -90 改为 -180,得到以下输出。
transform: scale(1) rotateY(-180deg);
现在我们已经做了足够的修改,还剩下一个小调整。如果你想让每张图片从左到右依次缩放,而不仅仅是中心图片,请按照以下步骤操作:
- 注释掉
.carousel
中的 "mask" 效果和 "overflow: hidden"。 - 在
.carousel .gallery
中添加 "margin-left: 50px;"。 - 注释掉
.carousel .gallery .card
中的 "position: absolute, left: 100%;",并添加 "margin: 0 20px;" 以增加图片之间的间隔。
这将产生以下输出。如有需要,进一步调整以满足你的需求。
.carousel {
/* overflow: hidden; */
/* mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent); */
}
.carousel .gallery {
margin-left: 50px;
}
.carousel .gallery .card {
/* position: absolute; */
/* left: 100% */
margin: 0 20px;
}
最后重要的是,它已经是响应式的!
如果你仍然想为不同屏幕调整图片大小,可以添加媒体查询。
/* 响应式 */
@media only screen and (max-width: 768px) {
.carousel .gallery .card {
width: calc(var(--wd) / 2 * 1px);
}
}
感谢大家!
点击此处查看实际演示。