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>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐