
本文详解如何用纯 css 构建三图循环轮播器,确保每张图片显示 4 秒、淡入淡出自然重叠无黑屏间隙,并提供可扩展的变量化方案适配动态图片数量。
本文详解如何用纯 css 构建三图循环轮播器,确保每张图片显示 4 秒、淡入淡出自然重叠无黑屏间隙,并提供可扩展的变量化方案适配动态图片数量。
要实现一个平滑、无闪烁、严格满足「每图显示 4 秒 + 交叉淡入淡出」的纯 CSS 轮播器(carousel),关键不在堆砌动画,而在于精确匹配动画总时长、单图停留时间与关键帧透明度曲线。常见错误(如原问题中出现的“显示过短”“出现黑屏间隙”)往往源于三处不一致:
- 动画总周期(
animation-duration)未按n × 单图时长设定; - 各图
animation-delay未等距递增; -
@keyframes中 opacity 过渡区间未覆盖「前一图淡出末段」与「后一图淡入初段」的重叠窗口。
✅ 正确解法(以 3 张图、每图净展示 4 秒为目标):
- 总动画周期 = 3 张 × 4 秒 = 12 秒(非 8 秒!原答案中“2s 每图”实际仅满足 2 秒净展示,不符合题设要求);
- 每张图
animation-delay分别设为0s、4s、8s,确保错峰启动; -
@keyframes需设计「15% 开始淡入 → 25% 完全可见 → 75% 开始淡出 → 85% 完全透明」,使相邻图片在 20%~30% 区间形成透明度叠加(即交叉淡变),彻底消除空白。
以下是符合题设(4 秒/图、3 图循环、无缝交叉淡入淡出)的完整代码:
.crossfade > figure {
animation: imageAnimation 12s linear infinite 0s;
backface-visibility: hidden;
background-size: cover;
background-position: center center;
color: transparent;
height: 100%;
left: 0;
opacity: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 0;
}
.crossfade {
height: 450px;
width: 100%;
position: relative;
}
.crossfade > figure:nth-child(1) {
background-image: url('https://picsum.photos/id/237/200/300');
}
.crossfade > figure:nth-child(2) {
animation-delay: 4s;
background-image: url('https://picsum.photos/seed/picsum/200/300');
}
.crossfade > figure:nth-child(3) {
animation-delay: 8s;
background-image: url('https://picsum.photos/200/300?grayscale');
}
@keyframes imageAnimation {
0%, 15% { opacity: 0; }
25%, 75% { opacity: 1; }
85%, 100% { opacity: 0; }
}
<div class="crossfade"> <figure></figure><figure></figure><figure></figure> </div>
? 关键参数说明(务必对照理解):
-
12s总周期 → 保证循环节奏稳定; -
animation-delay: 0s/4s/8s→ 每图相隔 4 秒启动,严格对齐生命周期; -
@keyframes中:-
0%–15%:当前图从 0→1(淡入,耗时 1.8s); -
25%–75%:保持完全不透明(净展示 4s 的核心区间); -
75%–85%:从 1→0(淡出,耗时 1.2s);
→ 因此第 1 图在75%(即 9s)开始淡出,而第 2 图早在4s(即33%)已进入淡入期,二者在75%–85%(9s–10.2s)重叠,实现视觉无缝过渡。
-
? 进阶:动态图片数量支持(推荐生产环境使用)
若图片由 JS 动态注入(如 API 获取),可借助 CSS 自定义属性避免硬编码:
.crossfade > figure {
--duration-per-image: 4s;
--total-images: 3;
animation: imageAnimation calc(var(--total-images) * var(--duration-per-image))
linear infinite 0s;
animation-delay: calc((var(--index) - 1) * var(--duration-per-image));
}
@keyframes imageAnimation {
0%, 12.5% { opacity: 0; }
20.8%, 79.2% { opacity: 1; }
87.5%, 100% { opacity: 0; }
}
<div class="crossfade"> <figure style="--index: 1; background-image: url(...)"></figure><figure style="--index: 2; background-image: url(...)"></figure><figure style="--index: 3; background-image: url(...)"></figure> </div>
? 注意事项总结:
- 务必为
.crossfade添加position: relative,否则绝对定位的figure会脱离文档流导致高度塌陷; -
backface-visibility: hidden可提升硬件加速兼容性,避免 Safari 等浏览器闪屏; - 所有
figure必须同级且无内容(仅靠background-image渲染),否则opacity: 0可能影响语义; - 如需响应式,建议用
aspect-ratio替代固定height,并配合background-size: cover保图完整性。
掌握这套时间映射逻辑(总时长 = 图数 × 单图时长 + 延迟 = (序号−1) × 单图时长 + 关键帧重叠区间 ≥ 10%),即可自由扩展至任意图片数量,真正实现零 JS、高性能、可维护的 CSS 轮播方案。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











