HTML + CSS 实现轮播图效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML+CSS实现轮播图</title>
<style>
* {
/* 清除内外边距 */
margin: 0;
padding: 0;
/* 清除li前面的小圆点 */
list-style: none;
}
body {
/* 弹性盒子布局 */
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
div.slide {
width: 200px;
height: 100px;
border: 1px solid purple;
/* 对超出部分隐藏 */
overflow: hidden;
/* 因为给labels设置了绝对定位,所有此处要加上相对定位(子绝父相) */
position: relative;
}
ul.list {
/* list的宽度等于li总个数乘以li的宽度 ,即可将元素一行排列*/
width: 800px;
/* 高度继承父元素slide的高度 */
height: inherit;
/* 降低list的层级,提高slide的层级,更好观察内部元素的移动 */
/* 此处注意:要设置元素z-index必须添加定位;也可以通过transform:translateZ()来提高显示层级 */
position: relative;
z-index: -1;
animation: move 5s ease 1s infinite;
}
li.item {
float: left;
width: 200px;
height: 100px;
/* 设置CSS3盒子模型 */
box-sizing: border-box;
border: 1px solid pink;
background-color: wheat;
color: #fff;
text-align: center;
line-height: 100px;
}
/* 添加动画实现自动播放效果 */
@keyframes move {
/*
此处的划分具体根据实际情况中轮播图中li的个数确定,即每个帧移动整数倍图片宽度
例如:5个li : 0% 25% 50% 75% 100%
4个li : 0% 33% 66% 100%
向左走为负,向右走为正
向上走为负,向下走为正
*/
0% {
transform: translate(0);
}
33% {
/* 向左走一个li宽度 */
transform: translate(-200px);
}
66% {
/* 向左走两个个li宽度 */
transform: translate(-400px);
}
100% {
/* 向左走两个个li宽度 */
transform: translate(-600px);
}
}
input {
/* 隐藏input,小圆点是通过label来实现的 */
display: none;
}
.labels {
position: absolute;
bottom: 5px;
/* 提高层级,不然显示不出来 */
z-index: 1;
width: inherit;
/* 使用flex布局 */
justify-content: center;
/* 隐藏小原点,当鼠标经过时才显示 */
display: none;
}
.slide:hover {
cursor: pointer;
}
.slide:hover .labels {
/* 鼠标经过时恢复原来的flex布局 */
display: flex;
}
.labels label {
box-sizing: border-box;
width: 8px;
height: 8px;
/* 设置为圆形 */
border-radius: 50%;
margin: 0 5px;
border: 1px solid #fff;
background-color: transparent;
/* 设置鼠标样式 */
cursor: pointer;
}
/*
element1~element2 选择器:
element1 之后出现的所有 element2。
两种元素必须拥有相同的父元素,但是 element2 不必直接紧随 element1。
为所有相同的父元素中位于 p 元素之后的所有 ul 元素设置背景:(即p与ul是兄弟元素)
p ~ ul {
background: #ff0000;
}
*/
input[id=pic1]:checked~.labels label[for=pic1],
input[id=pic2]:checked~.labels label[for=pic2],
input[id=pic3]:checked~.labels label[for=pic3] {
/* 通过属性选择器获得元素,当那个元素被选中时,通过兄弟元素找到labels下面的那个元素 */
background-color: #fff;
border: 1px solid #fff;
}
input[id=pic1]:checked~ul.list {
transform: translate(0);
}
input[id=pic2]:checked~ul.list {
transform: translate(-200px);
}
input[id=pic3]:checked~ul.list {
transform: translate(-400px);
}
/* 由于动画的原因,如果点击时不停止动画,此效果不会显示 */
.slide:hover .list {
/* 暂停动画,但是不能清除动画,动画效果还有 */
animation-play-state: paused;
/* 修改为完全清除动画 */
animation: none;
}
</style>
<!--
注:由于小圆点随着图片的移动的操作需要DOM,所以此案例更改为当鼠标经过图片时,显示小圆点
此方法还是有一点小漏洞,建议搭配js可做出更完善的效果。
-->
</head>
<body>
<div class="slide">
<!-- slide相当于一个视口,宽度不发生改变 -->
<!-- label一定要在ul.list前面,等下需要通过兄弟元素选择ul.list标签内的图片 -->
<!-- 按钮与下面的item是一一对应,通过选中那个按钮,下面item位移一定长度来展示相应信息 -->
<input type="radio" name="control" id="pic1" checked>
<input type="radio" name="control" id="pic2">
<input type="radio" name="control" id="pic3">
<!-- 由于点击按钮需要radio的checked属性,而且label可以通过for属性与input的id关联 -->
<!-- 由于input的样式不可控,所有以小圆点样式通过label生成的 -->
<div class="labels">
<label for="pic1"></label>
<label for="pic2"></label>
<label for="pic3"></label>
</div>
<!-- ul有几个li其宽度就是几个li总的宽度 -->
<ul class="list">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
<!-- 实现无缝切换在元素最后添加第一个元素 -->
<li class="item">1</li>
</ul>
</div>
</body>
</html>