Implement carousel functionality using pure HTML
, CSS
, and JavaScript
.
Use absolute and relative positioning with position
to implement the carousel. First, concatenate all the images into a single row. Use overflow: hidden;
to hide the other images. Add this row of images to a timer task that continuously moves them to the left, displaying only the middle image. Special handling is required for the edges. Append the first carousel image after the row of images. When switching to the last carousel image, the next image to be played is the first image. After this image carousel is complete, reset all the images. Two demos are provided: the first one is a simple carousel with no control buttons, and the second one is more comprehensive.
<!--
Simple demo, no controls, just image carousel
-->
```html
<!DOCTYPE html>
<html>
<head>
<title>Carousel</title>
<meta charset="utf-8">
<meta name="referrer" content="no-referrer">
</head>
<style type="text/css">
body{
margin: 0;
padding: 0px;
}
#carousel{
margin: auto; /* Center */
width: 600px; /* Set width */
position: relative; /* Relative positioning */
overflow: hidden; /* Hide overflow */
}
#carousel img{
width: 600px; /* Set size and scale proportionally */
}
#carousel > ul {
display: flex; /* Display images in one row */
position: absolute; /* Absolute positioning relative to #carousel */
}
#carousel > ul,
#carousel > ul > li{
padding: 0;
margin: 0;
list-style:none;
}
</style>
<body>
<!-- Carousel container -->
<div id="carousel">
<ul> <!-- Image container -->
<li>
<img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
</li>
</ul>
</div>
</body>
<script type="text/javascript">
var imgArr = []; // Array of images
var curIndex = 0; // Current displayed image
var timer = null; // Timer
function slide(slideContainer){
var width = imgArr[curIndex].width; // Get the width of the image, which is the distance to slide each time
var distanceMoved = 0; // Distance already moved
var step = 10; // Step of the slide
var curConLeft = slideContainer.offsetLeft; // Get the left position of the ul
var slideInterval = setInterval(function (){ // This timer is for the slide animation
if(Math.abs(width - distanceMoved) > step){ // Boundary check, check the difference between the distance moved and the distance to move with the step
curConLeft -= step; // Move continuously if greater than the step
slideContainer.style.left = `${curConLeft}px`; // Move
distanceMoved += step; // Add the step to the distance moved
}else{
clearInterval(slideInterval); // If the last distance moved is less than the step, clear the animation timer
slideContainer.style.left = `${curConLeft - width + distanceMoved }px`; // Complete the animation directly
distanceMoved = 0; // Reset the distance moved to 0
if(++curIndex === imgArr.length){ // Increment the index and check if it is the last image for edge handling
curIndex = 0; // Reset the index if it is the last image
slideContainer.style.left = 0; // Reset the ul
}
}
}, 10);
}
<body>
<div id="carousel">
<ul>
<li>
<img src="[to_be_replace1]">
</li>
</ul>
</div>
<div class="control">
<span class="prev"></span>
<span class="next"></span>
</div>
</body>
</html>
<style type="text/css">
body{
margin: 0;
padding: 0px;
}
#carousel{
margin: auto;
width: 600px;
position: relative;
overflow: hidden;
}
#carousel img{
width: 600px;
}
#carousel > ul {
display: flex;
position: absolute;
}
#carousel > ul,
#carousel > ul > li{
padding: 0;
margin: 0;
list-style:none;
}
.control{
position: absolute;
top: 50%;
left: 0;
right: 0;
text-align: center;
transform: translateY(-50%);
}
.control span{
display: inline-block;
width: 40px;
height: 40px;
background-color: rgba(0,0,0,0.5);
color: #fff;
font-size: 20px;
line-height: 40px;
cursor: pointer;
}
.control .prev{
margin-right: 20px;
}
.control .next{
margin-left: 20px;
}
</style>
/* Control button style */
#leftArrow,
#rightArrow{
position: absolute;
left: 5px;
top: 43%;
width: 25px;
height: 30px;
background-color: #eee;
display: flex;
justify-content: center;
align-items: center;
opacity: 0.7;
font-size: 20px;
cursor: pointer;
}
#rightArrow{
left: auto;
right: 5px;
}
#sliderBtn{
position: absolute;
width: 100%;
bottom: 0;
display: flex;
justify-content: flex-end;
}
.unitBtn{
width: 10px;
height: 10px;
background-color: #eee;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
.active{
background-color: #4C98F7;
}
<body>
<!-- Carousel container -->
<div id="carousel">
<ul> <!-- Image container -->
<li>
<img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
</li>
</ul>
<!-- Button group -->
<div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- Left arrow switch button -->
<div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- Right arrow switch button -->
<div id="sliderBtn"></div> <!-- Switch button group -->
</div>
</body>
<script type="text/javascript">
var imgArr = []; // Image array
var curIndex = 0; // Current displayed image
var timer = null; // Timer
var clickAllow = true; // Lock, whether the user is allowed to click
var btnList = []; // Right bottom switch button group
function slide(slideContainer , targetIndex = curIndex + 1){
var width = 0; // Calculate the distance to slide for switching images
if(targetIndex > curIndex){
for(let i=curIndex;i<targetIndex;++i) width+=imgArr[i].width; // Calculate the width from the current image to the subsequent images for forward switching
}else{
if(targetIndex === -1) width = imgArr[imgArr.length-1].width; // Special handling for the first image
else for(let i=targetIndex;i<curIndex;++i) width+=imgArr[i].width; // Handling for backward switching
}
clickAllow = false; // Do not allow the user to click
var step = width/60; // Dynamically set the step size
step = targetIndex > curIndex ? step : -step; // Forward or backward switching
var curConLeft = slideContainer.offsetLeft; // Get the left position of the ul
var distanceMoved = 0; // Distance already moved
var slideInterval = setInterval(function (){ // This timer is used to implement the switching animation
if(Math.abs(width - distanceMoved) > Math.abs(step)){ // Boundary judgment, compare the difference between the distance moved and the distance to be moved with the step size
curConLeft -= step; // Move continuously if the difference is greater than the step size
slideContainer.style.left = `${curConLeft - step}px`; // Move
distanceMoved += Math.abs(step); // Add the step size to the distance already moved
}else{
clearInterval(slideInterval); // If the last distance moved is less than the step size, clear the animation timer
var directMove = step > 0 ? (curConLeft - width + distanceMoved) : (curConLeft + width - distanceMoved); // Calculation method for forward and backward movement is different
slideContainer.style.left = `${directMove}px`; // Complete this animation directly
distanceMoved = 0; // Reset the distance moved to 0
curIndex = targetIndex; // Set the current index
if(curIndex === imgArr.length){ // Increment the index and check if it is the last image for edge handling
curIndex = 0; // Reset the index
slideContainer.style.left = `-${imgArr[0].width}px`; // Reset the ul
}else if (curIndex === -1) {
curIndex = imgArr.length-1; // Reset the index for the first image
slideContainer.style.left = `-${slideContainer.offsetWidth - imgArr[imgArr.length-1].width - imgArr[0].width}px`; // Reset the ul
}
switchBtnActive(); // Switch the right bottom button
clickAllow = true; // Allow clicking
}
}, 10);
}
</script>
function switchBtnActive() {
btnList.forEach((v) => {
v.className = "unitBtn"; // Set other buttons to gray
})
btnList[curIndex].className = "unitBtn active"; // Set the current button to blue
}
function createBtnGroup(carousel, slideContainer, config) {
document.getElementById("leftArrow").addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when manually switching
if (clickAllow) slide(slideContainer, curIndex - 1); // Switch to the previous slide if allowed to click
timer = setInterval(() => { slide(slideContainer) }, config.interval); // Reset the timer
})
document.getElementById("rightArrow").addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when manually switching
if (clickAllow) slide(slideContainer, curIndex + 1); // Switch to the next slide if allowed to click
timer = setInterval(() => { slide(slideContainer) }, config.interval); // Reset the timer
})
var sliderBtn = document.getElementById("sliderBtn"); // Get a reference to the button container
imgArr.forEach((v, i) => {
let btn = document.createElement("div"); // Create a button
btn.className = i === 0 ? "unitBtn active" : "unitBtn"; // Set the initial style of blue and gray buttons
btn.addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when manually switching
if (clickAllow) slide(slideContainer, i); // Switch if allowed to click
timer = setInterval(() => { slide(slideContainer) }, config.interval); // Reset the timer
})
btnList.push(btn); // Add the button to the button group
sliderBtn.appendChild(btn); // Append the button to the button container
})
}
function edgeDispose(slideContainer) {
var li = document.createElement("li"); // Create <li>
var img = document.createElement("img"); // Create new <img>
img.src = imgArr[0].src; // Set image src
li.appendChild(img); // Append <img> to <li>
slideContainer.appendChild(li); // Append the first image to the end of the carousel for edge handling
var li2 = document.createElement("li"); // Create <li>
var img2 = document.createElement("img"); // Create new <img>
img2.src = imgArr[imgArr.length - 1].src; // Set image src
li2.appendChild(img2); // Append <img> to <li>
slideContainer.insertBefore(li2, slideContainer.firstChild); // Append the last image to the beginning of the carousel for edge handling
slideContainer.style.left = `-${imgArr[0].width}px`; // Reset the position of the carousel
}
function eventDispose(carousel, slideContainer, config) {
document.addEventListener('visibilitychange', function() { // Listen for page visibility change to handle animation issues when switching pages
if (document.visibilityState == 'hidden') clearInterval(timer); // Clear the timer when the page is hidden
else timer = setInterval(() => { slide(slideContainer) }, config.interval); // Reset the timer
});
carousel.addEventListener('mouseover', function() { // Stop animation and timer when the mouse is over the carousel
clearInterval(timer); // Clear the timer
});
carousel.addEventListener('mouseleave', function() { // Start animation when the mouse leaves the carousel
timer = setInterval(() => { slide(slideContainer) }, config.interval); // Reset the timer
});
}
(function start() {
var config = {
height: "300px", // Configure height
interval: 5000 // Configure carousel interval
}
var carousel = document.getElementById("carousel"); // Get reference to container object
carousel.style.height = config.height; // Set carousel container height
document.querySelectorAll("#carousel img").forEach(v => imgArr.push(v)); // Get all images and create an array
var slideContainer = document.querySelector("#carousel > ul"); // Get the ul container for the row of images
edgeDispose(slideContainer); // Handle edge cases
eventDispose(carousel,slideContainer,config); // Handle browser events
createBtnGroup(carousel,slideContainer,config); // Handle button group
timer = setInterval(() => {slide(slideContainer)},config.interval); // Set timer for automatic slide
})();
</script>
</html>
First, the images are stacked by using absolute positioning, and the opacity
property is used to control the visibility of the images, so the image switching animation of the carousel is not controlled by JavaScript, but achieved using CSS animation. Since the images are stacked, using z-index
is also a feasible solution.
<!DOCTYPE html>
<html>
<head>
<title>Carousel</title>
<meta charset="utf-8">
<meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">
body{
margin: 0;
padding: 0px;
}
#carousel{
margin: auto; /* Center */
width: 600px; /* Set width */
position: relative; /* Relative positioning */
overflow: hidden; /* Hide overflow */
}
#carousel img{
position: absolute; /* Absolute positioning to stack images */
width: 600px; /* Set size and scale proportionally */
transition: all .6s; /* Animation */
opacity: 0; /* Hide */
}
.imgActive{
opacity: 1 !important; /* Show image with highest priority */
}
/* Control button style */
#leftArrow,
#rightArrow{
position: absolute;
left: 5px;
top: 43%;
width: 25px;
height: 30px;
background-color: #eee;
display: flex;
justify-content: center;
align-items: center;
opacity: 0.7;
font-size: 20px;
cursor: pointer;
z-index: 1000;
}
#rightArrow{
left: auto;
right: 5px;
}
#sliderBtn{
position: absolute;
width: 100%;
bottom: 0;
display: flex;
justify-content: flex-end;
z-index: 1000;
}
.unitBtn{
width: 10px;
height: 10px;
background-color: #eee;
border-radius: 10px;
margin: 10px;
cursor: pointer;
}
.btnActive{
background-color: #4C98F7;
}
</style>
<body>
<!-- Carousel container -->
<div id="carousel">
<img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
<img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
<img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
<img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
<!-- Button group -->
<div id="leftArrow" class="iconfont icon-arrow-lift"></div> <!-- Left arrow button -->
<div id="rightArrow" class="iconfont icon-arrow-right"></div> <!-- Right arrow button -->
<div id="sliderBtn"></div> <!-- Slider button group -->
</div>
</body>
<script type="text/javascript">
var imgArr = []; // Image array
var curIndex = 0; // Current displayed image
var timer = null; // Timer
var btnList = []; // Bottom right slider buttons
function slide(targetIndex = curIndex + 1){
curIndex = targetIndex % imgArr.length; // Get current index
imgArr.forEach((v) => v.className = "" ); // Hide other images
imgArr[curIndex] .className = "imgActive"; // Display current image
btnList.forEach(v => v.className = "unitBtn") // Set other buttons to gray
btnList[curIndex] .className = "unitBtn btnActive"; // Set current button to blue
}
function createBtnGroup(carousel, config) {
document.getElementById("leftArrow").addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when switching manually
slide(curIndex - 1); // Switch to the previous image if allowed
timer = setInterval(() => { slide() }, config.interval); // Reset the timer
})
document.getElementById("rightArrow").addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when switching manually
slide(curIndex + 1); // Switch to the next image if allowed
timer = setInterval(() => { slide() }, config.interval); // Reset the timer
})
var sliderBtn = document.getElementById("sliderBtn"); // Get the reference to the button container
imgArr.forEach((v, i) => {
let btn = document.createElement("div"); // Create a button
btn.className = i === 0 ? "unitBtn btnActive" : "unitBtn"; // Set the initial style of the button to blue or gray
btn.addEventListener('click', (e) => {
clearInterval(timer); // Clear the timer to avoid interference when switching manually
slide(i); // Switch if allowed
timer = setInterval(() => { slide() }, config.interval); // Reset the timer
})
btnList.push(btn); // Add the button to the button group
sliderBtn.appendChild(btn); // Append the button to the button container
})
}
function eventDispose(carousel, config) {
document.addEventListener('visibilitychange', function() { // Listening to page switch when the browser switches pages will cause animation problems
if (document.visibilityState == 'hidden') clearInterval(timer); // Clear the timer when the page is hidden
else timer = setInterval(() => { slide() }, config.interval); // Reset the timer
});
carousel.addEventListener('mouseover', function() { // When the mouse moves to the container, the animation is not switched, and the timer is stopped
clearInterval(timer); // Clear the timer when the page is hidden
});
carousel.addEventListener('mouseleave', function() { // When the mouse moves out of the container, the animation starts
timer = setInterval(() => { slide() }, config.interval); // Reset the timer
});
}
(function start() {
var config = {
height: "300px", // Configure the height
interval: 5000 // Configure the carousel interval
}
var carousel = document.getElementById("carousel"); // Get a reference to the container object
carousel.style.height = config.height; // Set the height of the carousel container
document.querySelectorAll("#carousel img").forEach((v, i) => {
imgArr.push(v); // Get all the images and create an array
v.className = i === 0 ? "imgActive" : "";
});
eventDispose(carousel, config); // Handle some browser events
createBtnGroup(carousel, config); // Handle the button group
timer = setInterval(() => { slide() }, config.interval); // Set the timer to switch at regular intervals
})();
Pure CSS
implementation of carousel, using CSS3
animation to complete the carousel, mainly using the animation
property and @keyframes
rule, using left
to control the distance, or opacity
, set the animation property for each image.
<!DOCTYPE html>
<html>
<head>
<title>Carousel</title>
<meta charset="utf-8">
<meta name="referrer" content="no-referrer">
</head>
<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1582902_u0zm91pv15i.css">
<style type="text/css">
body{
margin: 0;
padding: 0px;
}
#carousel{
margin: auto; /* Center */
width: 600px; /* Set width */
position: relative; /* Relative positioning */
overflow: hidden; /* Hide overflow */
height: 300px;
}
#carousel img{
width: 600px; /* Set size and scale proportionally */
}
#carousel > ul {
display: flex; /* Display images in a row */
position: absolute; /* Set absolute positioning relative to #carousel */
}
#carousel > ul,
#carousel > ul > li{
padding: 0;
margin: 0;
list-style:none;
}
#carousel > ul{
animation: switch 10s ease 1s infinite alternate; /* Set animation */
}
#carousel > ul:hover{
animation-play-state: paused; /* Pause animation on hover */
}
<style>
@keyframes switch{ /* Define animation rules */
0%,13%{
left: 0;
}
27%,41%{
left: -600px;
}
55%,69%{
left: -1200px;
}
83%,100% {
left: -1800px;
}
}
</style>
<body>
<!-- Carousel container -->
<div id="carousel">
<ul> <!-- Image container -->
<li>
<img src="http://www.sdust.edu.cn/__local/9/7A/B1/F29B84DEF72DD329997E8172ABA_664BA3EF_32466.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/B/F3/E4/693AB931C9FFB84646970D53BFE_C506394A_4282CA.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/F/7A/AA/E1459849AA8AB0C89854A41BD41_BF3BD857_BC0D8.jpg">
</li>
<li>
<img src="http://www.sdust.edu.cn/__local/1/95/CB/EDC1450B8FD1B8A25FAAC726AA4_A36D4253_16C91.jpg">
</li>
</ul>
</div>
</body>
</html>
https://github.com/WindrunnerMax/EveryDay