求助:无需JavaScript的CSS Image Carousel连续循环动画实现
纯CSS无缝轮播优化方案
问题分析
当前轮播的核心问题是动画结束后直接跳回起始位置,产生明显断层;且轨道长度不足,滑动到后期会出现空白。要实现无JS无缝循环,需通过复制轮播项填充轨道,并调整动画逻辑,让视觉上实现连续循环。
优化步骤
- 填充轮播轨道:将各终端一次显示的轮播项(桌面端5个、平板2个、移动端1个)复制到轨道末尾,确保滑动到原最后一项时,后续衔接开头内容,视觉连贯。
- 调整动画关键帧:让动画滑过完整的原轨道长度后,利用复制内容衔接开头,借助动画循环特性实现无缝重置,用户无感知。
- 适配多终端动画:针对不同终端的item宽度,设置对应动画参数,保证各设备上的循环效果一致。
完整代码
CSS 代码
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } .st-carousel-container { display: flex; align-items: center; position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .st-carousel { width: 100%; margin-left: auto; margin-right: auto; padding-left: 48px; padding-right: 48px; position: relative; } .st-carousel__screen { overflow: hidden; margin-left: -16px; margin-right: -16px; } .st-carousel__track { font-size: 0; white-space: nowrap; -webkit-overflow-scrolling: touch; animation: slide 28s linear infinite; } .st-carousel__item { display: inline-flex; padding-left: 16px; padding-right: 16px; vertical-align: top; white-space: normal; } .st-carousel__item--desktop-in-1 { width: 100%; } .st-carousel__item--desktop-in-2 { width: 50%; } .st-carousel__item--desktop-in-3 { width: 33.3333333333%; } .st-carousel__item--desktop-in-4 { width: 25%; } .st-carousel__item--desktop-in-5 { width: 20%; } .st-carousel__item-content { color: #fff; display: flex; font-weight: 100; align-items: center; justify-content: center; text-transform: uppercase; border-radius: 3px; font-size: 56px; height: 250px; width: 100%; } .st-carousel__item:nth-child(1) .st-carousel__item-content { background-color: #216485; } .st-carousel__item:nth-child(2) .st-carousel__item-content { background-color: #3692b6; } .st-carousel__item:nth-child(3) .st-carousel__item-content { background-color: #6fccc9; } .st-carousel__item:nth-child(4) .st-carousel__item-content { background-color: #a6e3cf; } .st-carousel__item:nth-child(5) .st-carousel__item-content { background-color: #aff0be; } .st-carousel__item:nth-child(6) .st-carousel__item-content { background-color: #527059; } .st-carousel__item:nth-child(7) .st-carousel__item-content { background-color: #243127; } .st-carousel__item--clone:nth-child(8) .st-carousel__item-content { background-color: #216485; } .st-carousel__item--clone:nth-child(9) .st-carousel__item-content { background-color: #3692b6; } .st-carousel__item--clone:nth-child(10) .st-carousel__item-content { background-color: #6fccc9; } .st-carousel__item--clone:nth-child(11) .st-carousel__item-content { background-color: #a6e3cf; } .st-carousel__item--clone:nth-child(12) .st-carousel__item-content { background-color: #aff0be; } @media screen and (max-width: 1023px) { .st-carousel { padding-left: 0; padding-right: 0; } .st-carousel__screen { margin-left: 0; margin-right: 0; } .st-carousel__track { overflow-x: auto; width: auto; padding-left: 48px; padding-right: 48px; animation: slide-tablet 27s linear infinite; } .st-carousel__item--tablet-in-1 { width: 90%; } .st-carousel__item--tablet-in-2 { width: 45%; } .st-carousel__item--tablet-in-3 { width: 30%; } } @media screen and (max-width: 650px) { .st-carousel__track { padding-left: 0; padding-right: 0; animation: slide-mobile 32s linear infinite; } .st-carousel__item--mobile-in-1 { width: 90%; } .st-carousel__item--mobile-in-2 { width: 45%; } .st-carousel__item--mobile-in-3 { width: 30%; } } @keyframes slide { 0% { transform: translateX(0); } 100% { transform: translateX(-140%); } } @keyframes slide-tablet { 0% { transform: translateX(0); } 100% { transform: translateX(-315%); } } @keyframes slide-mobile { 0% { transform: translateX(0); } 100% { transform: translateX(-630%); } }
HTML 代码
<div class="st-carousel-container"> <div class="st-carousel"> <div class="st-carousel__screen"> <div class="st-carousel__track"> <!-- 原轮播项 --> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">a</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">b</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">c</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">d</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">e</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">f</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5"> <div class="st-carousel__item-content">g</div> </div> <!-- 复制轮播项实现无缝衔接 --> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5 st-carousel__item--clone"> <div class="st-carousel__item-content">a</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5 st-carousel__item--clone"> <div class="st-carousel__item-content">b</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5 st-carousel__item--clone"> <div class="st-carousel__item-content">c</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5 st-carousel__item--clone"> <div class="st-carousel__item-content">d</div> </div> <div class="st-carousel__item st-carousel__item--mobile-in-1 st-carousel__item--tablet-in-2 st-carousel__item--desktop-in-5 st-carousel__item--clone"> <div class="st-carousel__item-content">e</div> </div> </div> </div> </div> </div>
额外说明
- 动画时长可根据需求调整,当前设置为每个轮播项停留+切换共4秒,保证节奏平稳。
- 复制项数量对应各终端一次显示的item数,确保滑动到末尾时,后续内容与开头一致,消除循环断层。
内容的提问来源于stack exchange,提问作者Vinicius Garcia
相关产品推荐
相关产品推荐

