使用CSS实现无限滚动轮播






1.60/5 (3投票s)
仅使用CSS3(无JavaScript和JS框架)的轮播。
引言
许多UI/UX框架(如Bootstrap、Glide、Flickity等)都提供了许多现成的轮播图解决方案。但如果我们想在不依赖任何第三方库的情况下,使用HTML5和CSS3构建一个轮播图呢?本文介绍如何构建一个简单的、无需任何JS代码的轮播图。
背景
在本文中,我们将使用4个不同颜色的DIV来创建一个无限滚动的轮播图。
步骤1:创建DIV并设置样式
首先,我们将创建4个div,并将它们放在一个父容器中。
<div class="gallery">
  <div class="red"></div>
  <div class="blue"></div>
  <div class="yellow"></div>
  <div class="green"></div>
</div>
CSS类将如下所示
.gallery {
position: relative;
width:100%; /* takes the parent div's width*/
}
.gallery >div{
position: absolute;
top:0;
height: 200px; /* can be anything */
width: 100%;
}
注意:父div的位置是相对的,所有子div都是绝对定位的。所有div都将一个接一个地放置在父div'gallery'中。
步骤2:创建用于切换轮播图的控件
这部分比较有趣,我们需要一些按钮/控件来浏览我们的轮播图。但是,如果我们使用HTML按钮,则需要一个onclick事件监听器,而这又需要由JavaScript处理。
让我们用CSS的方式来做。我们将使用单选按钮而不是按钮。
为每个div创建一个单选按钮。这里的想法是,如果单选按钮1被选中,则显示div 1,依此类推。
<div class="carousel-container">
 <input type="radio" name='control' id="slide1" class="carousel-control-radio">
 <input type="radio" name='control' id="slide2" class="carousel-control-radio">
 <input type="radio" name='control' id="slide3" class="carousel-control-radio">
 <input type="radio" name='control' id="slide4" class="carousel-control-radio">
 <div class="gallery">
  <div class="red"></div>
  <div class="blue"></div>
  <div class="yellow"></div>
  <div class="green"></div>
 </div>
</div>
在HTML5中,<label>标签有一个属性“for”,它用于将输入元素与其标签关联起来。此属性的另一个有趣特性是:当我们点击分配给它的标签时,相应的单选按钮会被选中。我们将使用此特性来利用我们的控件。
注意:我已经将整个HTML块包含在一个名为carousel-container的div中,其位置为相对定位,宽度任意。
让我们实现控件。逻辑是将所有div的不透明度设置为0,并将选定div的不透明度设置为1。
.gallery >div{ 
position: absolute;
top:0; 
height: 200px; /* can be anything */ 
width: 100%; 
opacity:0 /* all divs are hidden */
}
我们将覆盖所选单选按钮的div的不透明度。我们该怎么做呢?
通用兄弟组合子 (~):它用于选择选择器之后的所有兄弟元素。
#slide1:checked ~ .gallery > div:nth-child(1),
#slide2:checked ~ .gallery > div:nth-child(2),
#slide3:checked ~ .gallery > div:nth-child(3),
#slide4:checked ~ .gallery > div:nth-child(4)
{
  opacity: 1;
}
#slide1:checked ~ .gallery > div:nth-child(1) 表示当#slide1被选中时,从其后的兄弟元素中选择 -> .gallery div及其第一个子元素。我们将opacity设置为1。
现在我们的输出应该如下所示

步骤3:为每个单选按钮创建标签
<div class="slider-controls">
  <label for="slide1"></label>
  <label for="slide2"></label>
  <label for="slide3"></label>
  <label for="slide4"></label>
</div>
现在我们需要将滑块控件放在轮播图容器的中心。
.slider-controls{
 position: absolute;
 width: 100%;
 top:100px;
}
注意:标签内没有文本。没错!我们将使用CSS伪元素动态更改文本内容为“<”或“>”,这将表示前一个或下一个div的方向。
根据我们的设计,当选择其对应的单选按钮时,我们将显示div。
例如,如果选中单选按钮slide2:“<”应该是当点击时切换到slide 1的控件,“>”应该是当点击时切换到slide 3的控件。
所以:
#slide2:checked ~ .slider-controls > label:nth-child(3)::after{
 content: '>';
 float:right; /*push the control on the right side*/
}
#slide2:checked ~ .slider-controls > label:nth-child(1)::after{
 content: '<';
 float:left; /*push the control on the left side*/
}
我们不需要显示任何其他控件。我们只需要显示这两个。
#slide3:checked ~ .slider-controls > label:nth-child(4)::after{
 content: '>';
 float:right; /*push the control on the right side*/
}
#slide3:checked ~ .slider-controls > label:nth-child(2)::after{
 content: '<';
 float:left; /*push the control on the left side*/
}
#slide4:checked ~ .slider-controls > label:nth-child(1)::after{
 content: '>';
 float:right; /*push the control on the right side*/
}
#slide4:checked ~ .slider-controls > label:nth-child(3)::after{
 content: '<';
 float:left; /*push the control on the left side*/
}
注意:slide 4的下一个将是slide 1。
现在第一个slide有点棘手。
它将有指向slide 2的“>”(直接指向)。而“<”应该指向最后一个slide。我们将使用nth-last-child(1)伪元素来选择最后一个div。
#slide1:checked ~ .slider-controls > label:nth-child(2)::after{
 content: '>'
 float:right; /*push the control on the right side*/
}
#slide1:checked ~ .slider-controls > label:nth-last-child(1)::after{
 content: '<'
 float:left; /*push the control on the left side*/
}
这就完成了我们的解决方案。

改进
- 我们还可以添加CSS过渡来使我们的不透明度过渡更加平滑。.gallery >div{ position: absolute; top:0; height: 200px; /* can be anything */ width: 100%; opacity:0 /* all divs are hidden */ transtion: opacity 800ms ease-in-out; }
- 可以使用display:none隐藏顶部的单选按钮,解决方案仍然有效。
- 可以使用伪元素上的边框来设计伪选择器的内容,而不是“>”或“<”。
- 可以将div的背景设置为图像,从而创建一个漂亮的图像库。


