纯CSS实现轮播

By | 2022-04-24

1. 把图片水平排列

<div class="banner">
  <div class="banner-wrapper">
  <ul class="banner-list">
   <li class="item" id="item1">1</li>
   <li class="item" id="item2">2</li>
   <li class="item" id="item3">3</li>
   <li class="item" id="item4">4</li>
  </ul>
 </div>
</div>

CSS代码如下:

.banner {
    border: 4px solid black;
    width: 300px;
    height: 150px;
    box-sizing: content-box;
}
.banner .banner-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: -1;
}
.banner-list {
    width: 1200px;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    padding: 0;
    margin: 0;
    list-style: none;
}
.banner-list .item {
    width: 300px;
    height: 100%;
    display: inline-block;
    float: left;
    font-weight: bold;
    font-size: 40px;
    line-height: 150px;
}
.banner-list .item#item1{
    background: #fee2b3;
}
.banner-list .item#item2 {
    background: #ffa299;
}
.banner-list .item#item3 {
    background: #ad6989;
}
.banner-list .item#item4 {
    background: #562349;
}

图中黑色框代表屏幕中显示的区域,超出部分不可见。html代码没啥好说的,一个容器,里面套需要轮播的图片,我们看css代码,所谓轮播,就是不停的切换显示区域,代码操作就是左右移动轮播列表,这里我们用leftright属性操作,所以就要把轮播列表的position设置成absolute,它的父节点的position设置成relative,即轮播列表相对于父节点是绝对位置,比如left: 10px,就代表列表左边距父节点一定是10px,不管你父节点如何变化,都是这么多。水平排列,不要忘记一个重要属性float,把float: left设置到每一个轮播项中,代表排列的时候做对齐。

2. 隐藏轮播图外部区域

如上图所示,最终轮播区域是在黑色框中,而外部区域是不希望看到的,现在需要把它隐藏掉:

.banner .banner-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

使用overflow: hidden把溢出容器的部分隐藏。

3. 动起来

前面的准备操作基本都差不多了(没看懂的小伙伴多看几遍,最好是动手敲一边),现在是时候让我们的轮播图滚动起来了。前面也说了,所谓滚动,就是不停的平移轮播列表,这时候需要使用CSS帧动画(keyframes) 代码如下:

@keyframes banner-swipe {
    0% { left: 0; }
    33.33% { left: -300px; }
    66.66% { left: -600px; }
    100% { left: -900px; }
}

.banner-list {
    width: 1500px;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    padding: 0;
    margin: 0;
    list-style: none;
    animation: banner-swipe 10s ease-in infinite;
}

定义了一个帧动画,因为有4张图,所以只要滚动三次就能全部播放完图片,把整个滚动时间看作100%,那么一帧大约33.33%,而在banner-list上,我们给它绑定上帧动画banner-swipe,规定完成一次动画要10s,滚完之后不要停,一直无限循环(infinite),效果如下:

发现有缺陷,第四张图和第一张图之间切换时,会很快,原因是到第四张图停止滚动时,整个动画已经执行完了,就会立马回到第一张图,从0开始,我们把隐藏部分打开看一下:

动图中很明显了,4过后立马跳到了1,解决办法是在4后面加一个1,帧动画里面再插入一帧,代码如下:

<div class="banner-list">
  <div class="item" id="item1">1</div>
  <div class="item" id="item2">2</div>
  <div class="item" id="item3">3</div>
  <div class="item" id="item4">4</div>
  <div class="item" id="item1">1</div>
</div>
@keyframes banner-swipe {
    0% { left: 0; }
    25% { left: -300px; }
    50% { left: -600px; }
    75% { left: -900px; }
    100% { left: -1200px; }
}

通过上面的修改,保证了滚动的连续性。

现在还有一个问题,每张图片几乎没有停过,一直在滚动,这样肯定达不到推广的作用而且也会使人眼花缭乱,需要再优化,修改后的帧动画如下:

@keyframes banner-swipe {
    0% { left: 0; }
    23% {left: 0;}
    25% { left: -300px; }
    48% {left: -300px;}
    50% { left: -600px; }
    73% { left: -600px; }
    75% { left: -900px; }
    98% { left: -900px; }
    100% { left: -1200px; }
}