如何为3D Carousel添加导航控制箭头?
3D轮播添加手动导航箭头的实现方案
实现步骤
1. 添加导航箭头的HTML结构
在.container内部、.cards容器的前后添加左右箭头按钮,代码如下:
<div class="container"> <!-- 保留原有的radio输入项 --> <input type="radio" name="slider" class="d-none" id="s1" checked> <input type="radio" name="slider" class="d-none" id="s2"> <input type="radio" name="slider" class="d-none" id="s3"> <input type="radio" name="slider" class="d-none" id="s4"> <input type="radio" name="slider" class="d-none" id="s5"> <!-- 左箭头按钮 --> <button class="carousel-arrow carousel-arrow-left" id="prevBtn">‹</button> <!-- 保留原有的cards轮播容器 --> <div class="cards"> <!-- 原有的slide内容 --> </div> <!-- 右箭头按钮 --> <button class="carousel-arrow carousel-arrow-right" id="nextBtn">›</button> </div>
2. 添加箭头的CSS样式
在原有<style>标签中添加以下样式,实现箭头的定位与美化:
/* 导航箭头基础样式 */ .carousel-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; border: none; border-radius: 50%; background-color: rgba(255,255,255,0.8); color: #333; font-size: 28px; cursor: pointer; z-index: 10; transition: background-color 0.3s ease; } .carousel-arrow:hover { background-color: rgba(255,255,255,1); } /* 左箭头定位 */ .carousel-arrow-left { left: -70px; } /* 右箭头定位 */ .carousel-arrow-right { right: -70px; }
同时修改.container的样式,添加position: relative确保箭头能基于容器定位:
.container { width: 100%; height: 100%; max-width: 600px; max-height: 600px; display: flex; transform-style: preserve-3d; justify-content: center; align-items: center; flex-direction: column; position: relative; /* 添加这行 */ /* margin-left: 450px; 可根据布局需求保留或删除 */ }
3. 添加JavaScript切换逻辑
在<body>末尾添加脚本,监听箭头点击事件,实现轮播项的切换:
<script> const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const slides = document.querySelectorAll('input[name="slider"]'); let currentIndex = 0; // 初始化当前选中的轮播项索引 slides.forEach((slide, index) => { if (slide.checked) { currentIndex = index; } }); // 点击右箭头切换到下一项 nextBtn.addEventListener('click', () => { currentIndex = (currentIndex + 1) % slides.length; slides[currentIndex].checked = true; }); // 点击左箭头切换到上一项 prevBtn.addEventListener('click', () => { currentIndex = (currentIndex - 1 + slides.length) % slides.length; slides[currentIndex].checked = true; }); </script>
修改后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D Carousel</title> <style> @import url('https://fonts.googleapis.com/css2?family=Urbanist:wght@200;300;400;600;700&display=swap'); .carrusel-nuevos { display: flex; align-items: center; justify-content: center; overflow-x: hidden; height: 100vh; font-family: 'Urbanist', sans-serif; } a { text-decoration: none; } input { display: none; } .container { width: 100%; height: 100%; max-width: 600px; max-height: 600px; display: flex; transform-style: preserve-3d; justify-content: center; align-items: center; flex-direction: column; position: relative; /* margin-left: 450px; 按需保留 */ } .cards { position: relative; height: 500px; width: 430px; margin-bottom: 20px; perspective: 1000px; transform-style: preserve-3d; } .cards label { position: absolute; width: 430px; left: 0; right: 0; margin: auto; cursor: pointer; transition: transform 0.55s ease; } .cards .card{ position: relative; height: 100%; border-radius: 10px; padding: 30px 35px; } .card .image{ display: flex; justify-content: center; } .card { border-radius: 5px; margin-top: 23px; } .image img { width: 100%; height: 100%; object-fit: cover; } .card .image .dots{ text-align: center; } .dots div{ width: 10px; height: 10px; border-radius: 50%; margin-bottom: 10px; } .dots div:nth-child(1){ background-color: var(--current-color1); } .dots div:nth-child(2){ background-color: #5B85F9; } .dots div:nth-child(3){ background-color: #000; } .card .infos{ display: block; text-align: end; padding-top: 60px; } .infos span{ display: block; } .infos .name{ font-size: 20px; color: var(--current-color1); margin-bottom: 20px; text-align: center; transition: all .6s ease; } .infos .lorem{ font-size: 15.5px; color: #ECEAED; letter-spacing: 3px; } .card .socials{ display: flex; justify-content: space-between; align-items: center; padding-top: 20px; } .socials i{ font-size: 25px; transition: all .7s ease; color: var(--current-color2); } #s1:checked~.cards #slide4, #s2:checked~.cards #slide5, #s3:checked~.cards #slide1, #s4:checked~.cards #slide2, #s5:checked~.cards #slide3 { transform: translate3d(-70%, 0, -220px); --current-color1: #ECEAED; --current-color2: #404457; filter: blur(5px); } #s1:checked~.cards #slide5, #s2:checked~.cards #slide1, #s3:checked~.cards #slide2, #s4:checked~.cards #slide3, #s5:checked~.cards #slide4 { transform: translate3d(-35%, 0, -120px); --current-color1: #ECEAED; --current-color2: #404457; filter: blur(5px); } #s1:checked~.cards #slide1, #s2:checked~.cards #slide2, #s3:checked~.cards #slide3, #s4:checked~.cards #slide4, #s5:checked~.cards #slide5 { transform: translate3d(0, 0, 0); --current-color1: rgb(242, 117, 154); --current-color2: #ECEAED; } #s1:checked~.cards #slide2, #s2:checked~.cards #slide3, #s3:checked~.cards #slide4, #s4:checked~.cards #slide5, #s5:checked~.cards #slide1 { transform: translate3d(35%, 0, -120px); --current-color1: #ECEAED; --current-color2: #404457; filter: blur(5px); } #s1:checked~.cards #slide3, #s2:checked~.cards #slide4, #s3:checked~.cards #slide5, #s4:checked~.cards #slide1, #s5:checked~.cards #slide2 { transform: translate3d(70%, 0, -220px); --current-color1: #ECEAED; --current-color2: #404457; filter: blur(5px); } /* 导航箭头样式 */ .carousel-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; border: none; border-radius: 50%; background-color: rgba(255,255,255,0.8); color: #333; font-size: 28px; cursor: pointer; z-index: 10; transition: background-color 0.3s ease; } .carousel-arrow:hover { background-color: rgba(255,255,255,1); } .carousel-arrow-left { left: -70px; } .carousel-arrow-right { right: -70px; } </style> </head> <body class="carrusel-nuevos"> <div class="container"> <input type="radio" name="slider" class="d-none" id="s1" checked> <input type="radio" name="slider" class="d-none" id="s2"> <input type="radio" name="slider" class="d-none" id="s3"> <input type="radio" name="slider" class="d-none" id="s4"> <input type="radio" name="slider" class="d-none" id="s5"> <button class="carousel-arrow carousel-arrow-left" id="prevBtn">‹</button> <div class="cards"> <label for="s1" id="slide1"> <div class="card"> <div class="image"> <img src="image-1.jpg" alt=""> </div> <div class="infos"> <span class="name">Bodysuit Shaper Thong Strapless Dailyweat Everntwear Falas</span> </div> </div> </label> <label for="s2" id="slide2"> <div class="card"> <div class="image"> <img src="image-2.jpg" alt=""> </div> <div class="infos"> <span class="name">Free Run Flyknit</span> </div> </div> </label> <label for="s3" id="slide3"> <div class="card"> <div class="image"> <img src="image-3.jpg" alt=""> </div> <div class="infos"> <span class="name">Black Toe Union</span> </div> </div> </label> <label for="s4" id="slide4"> <div class="card"> <div class="image"> <img src="image-4.jpg" alt=""> </div> <div class="infos"> <span class="name">Retro High Og</span> </div> </div> </label> <label for="s5" id="slide5"> <div class="card"> <div class="image"> <img src="image-5.jpg" alt=""> </div> <div class="infos"> <span class="name">Off-White Air Jordan</span> </div> </div> </label> </div> <button class="carousel-arrow carousel-arrow-right" id="nextBtn">›</button> </div> <script> const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const slides = document.querySelectorAll('input[name="slider"]'); let currentIndex = 0; // 初始化当前选中的轮播项索引 slides.forEach((slide, index) => { if (slide.checked) { currentIndex = index; } }); // 切换到下一个轮播项 nextBtn.addEventListener('click', () => { currentIndex = (currentIndex + 1) % slides.length; slides[currentIndex].checked = true; }); // 切换到上一个轮播项 prevBtn.addEventListener('click', () => { currentIndex = (currentIndex - 1 + slides.length) % slides.length; slides[currentIndex].checked = true; }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Fabio Chirino Spades
相关产品推荐
相关产品推荐

