纯html+css仅能实现基于@keyframes的固定张数渐变轮播,如opacity淡入淡出或clip-path百叶窗;display切换不支持动画,必须用position: absolute叠层;radio方案交互弱且无法真正并发控制多图。

纯 HTML + CSS 做不出真正“渐变轮播图”——opacity 可以淡入淡出,但“渐变”若指颜色过渡、遮罩推移、百叶窗或滑动叠加等效果,CSS 本身不提供逐帧控制逻辑,必须靠 @keyframes 精确编排动画时序,且仅适用于固定张数、预知顺序的静态轮播。
为什么 display: none / block 不适合做渐变切换
因为 display 是离散属性,无法参与 transition 或 @keyframes 动画。强行用它切换,只会闪现,没有中间态。所谓“渐变”,本质是多个元素在相同时空位置上,通过 opacity、transform、clip-path 等可动画属性协同变化实现的视觉混合效果。
- 所有轮播项必须用
position: absolute叠在同一位置,否则无法叠加渐变 - 不能依赖 JS 动态增删 class 控制状态——纯 CSS 方案必须把全部状态写死在
@keyframes里 - 图片数量必须已知(比如 3 张或 5 张),否则动画关键帧时间点无法对齐
- 浏览器兼容性:Firefox 121+ 和 Chrome 120+ 支持
clip-path: polygon()动画,但 Safari 仍有限制
用 @keyframes + opacity 实现最简淡入淡出轮播
这是唯一无需 JS、兼容性最好、且真能叫“渐变”的方案。核心是让每张图在总周期中各占一段“可见窗口”,靠 opacity 过渡衔接。
- 假设有 3 张图,每张停留 3s,总周期为 9s,则每张图的
opacity关键帧需覆盖 3s 区间,并前后预留 0.5s 重叠过渡 - 容器必须设
height和overflow: hidden,防止布局抖动 - 每张
<img>需设position: absolute; top: 0; left: 0; width: 100%; height: 100% - 动画名要唯一,避免多个轮播组件互相干扰,例如命名为
fade-3
@keyframes fade-3 {
0%, 33.33% { opacity: 1; }
33.34%, 66.66% { opacity: 0; }
66.67%, 100% { opacity: 0; }
}
/* 实际需为每张图单独写一版,起始偏移不同 */
.slide:nth-child(1) { animation: fade-3 9s infinite 0s; }
.slide:nth-child(2) { animation: fade-3 9s infinite 3s; }
.slide:nth-child(3) { animation: fade-3 9s infinite 6s; }
用 clip-path 模拟“百叶窗”渐变切换(Chrome 120+ / Firefox 121+)
比 opacity 更具视觉表现力,但必须接受它不是“通用渐变”,而是对特定切割形状的动画。关键在于 clip-path: polygon() 的顶点坐标必须全程线性插值,否则会跳变。
- 只支持偶数条“窗格”,例如 6 条,需将一张图切为 6 个
<div> 子块,每块包一层 <code><img>并设相同background-image - 每块初始
clip-path: polygon(0 0, 0 0, 0 0, 0 0)(即完全隐藏),结束时展开为完整矩形 - 各块动画延迟需错开,如
animation-delay: 0.1s,0.2s… 才有“依次扫过”感 - 务必加
will-change: clip-path提升渲染性能,否则在低端设备易卡顿 - 你写的
.slides input[type="radio"]:nth-of-type(2):checked ~ .slide只能让第 2 张之后的所有.slide变化,第 1 张不受影响 - 若想让第 1 张淡出、第 2 张淡入,必须给第 1 张也写一条独立规则:
input:nth-of-type(1):checked ~ .slide:nth-child(1),逐张枚举 - 一旦图片数变动,所有
@keyframes和选择器都要重算,维护成本远高于加 20 行 JS
radio + ~ 选择器方案的渐变局限
这种“伪轮播”看似无 JS,实则交互能力极弱:用户只能点 dot 切换,无法悬停暂停、无法键盘导航、无法响应 swipe。更关键的是,它无法实现多图同时参与的渐变——因为 :checked ~ .slide 只能选中后续兄弟,无法回溯或并发控制。
真正需要“渐变”又不愿写 JS 的场景极少;多数情况下,加一个 opacity 过渡 + transition 就已足够,而复杂动画本就该交给 JS 控制节奏和状态——CSS 负责描边,JS 负责运笔。











