Оставляем для вас ниже готовый код для создания простой карусели с изображениями.
html
<div class="wrapper flex-center-all">
<div class="img-container">
<img src="https://plus.unsplash.com/premium_photo-1684992858411-3e3ddf37c4c9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80"
alt="jellyfish" class="visible" id="img-1">
<img src="https://images.unsplash.com/photo-1495012379376-194a416fcc5f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=725&q=80"
alt="jellyfish" class="hidden" id="img-2">
<img src="https://images.unsplash.com/photo-1543007168-5fa9b3c5f5fb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=688&q=80"
alt="jellyfish" class="hidden" id="img-3">
<img src="https://images.unsplash.com/photo-1540968221243-29f5d70540bf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=627&q=80"
alt="jellyfish" class="hidden" id="img-4">
<img src="https://images.unsplash.com/photo-1601827196754-8a06c1891d35?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=687&q=80"
alt="jellyfish" class="hidden" id="img-5">
</div>
<div class="next-prev-btns">
<div class="prev-btn-container flex-center-all">
<button class="prev-btn flex-center-all">‹</button>
</div>
<div class="next-btn-container flex-center-all">
<button class="next-btn flex-center-all">›</button>
</div>
</div>
<div class="img-nav-container">
<div class="img-nav-item img-nav-item-selected">
<div class="outer-circle pos-center-all"></div>
<div class="inner-circle pos-center-all"></div>
</div>
<div class="img-nav-item">
<div class="outer-circle pos-center-all"></div>
<div class="inner-circle pos-center-all"></div>
</div>
<div class="img-nav-item">
<div class="outer-circle pos-center-all"></div>
<div class="inner-circle pos-center-all"></div>
</div>
<div class="img-nav-item">
<div class="outer-circle pos-center-all"></div>
<div class="inner-circle pos-center-all"></div>
</div>
<div class="img-nav-item">
<div class="outer-circle pos-center-all"></div>
<div class="inner-circle pos-center-all"></div>
</div>
</div>
</div>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
/* --- UTILITY CLASSES --- */
.flex-center-all {
display: flex;
align-items: center;
justify-content: center;
}
.pos-center-all {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* ----------------------- */
.wrapper {
height: 100vh;
position: relative;
background: #eee;
}
.img-container {
width: 60vw;
height: 60vw;
}
img {
width: 100%;
height: 100%;
/* object-fit: cover; */
}
.visible {
display: inline;
transition: all 0.125s;
}
.hidden {
display: none;
transition: all 0.125s;
}
.next-prev-btns {
position: absolute;
height: 10vh;
width: 100vw;
display: flex;
justify-content: space-between;
padding: 0 7vw;
align-items: center;
}
.prev-btn-container,
.next-btn-container {
height: 8vw;
width: 8vw;
}
button {
background: none;
border: 0;
font-size: 10vw;
border-radius: 50%;
background: #387ca1;
width: 100%;
height: 100%;
padding-bottom: 1.25vw;
color: #ddd;
transition: all 0.125s;
}
button:hover {
cursor: pointer;
background: #54b9f0;
color: white;
transition: all 0.125s;
}
.img-nav-container {
position: absolute;
bottom: 0;
height: 4vw;
top: calc(50% + 33vw);
display: flex;
justify-content: space-around;
align-items: center;
}
.img-nav-item {
width: 4vw;
height: 100%;
position: relative;
}
.img-nav-item:not(:last-child) {
margin-right: 0.5vw;
}
.inner-circle {
cursor: pointer;
width: 2vw;
height: 2vw;
background: black;
border-radius: 50%;
box-sizing: content-box;
border: 0.5vw solid white;
}
.img-nav-item-selected > .inner-circle,
.img-nav-item-selected > .outer-circle {
cursor: unset;
}
.outer-circle {
cursor: pointer;
position: absolute;
width: 3.5vw;
height: 3.5vw;
border-radius: 50%;
transition: background 0.125s;
}
.img-nav-item-selected > .outer-circle {
background: #999;
transition: background 0.125s;
}
.img-nav-item:hover > .outer-circle {
width: 3.75vw;
height: 3.75vw;
background: black;
cursor: pointer;
}
/* override */
.img-nav-item-selected:hover > .outer-circle {
width: 3.5vw;
height: 3.5vw;
background: #999;
cursor: unset;
}
/* screen is taller than wide */
/* @media (max-aspect-ratio: 100/99) {
.wrapper {
background: blue;
}
} */
/* screen is wider than tall */
@media (min-aspect-ratio: 99/100) {
.img-container {
width: 60vh;
height: 60vh;
}
.next-prev-btns {
height: 10vw;
width: 100vh;
padding: 0 7vh;
}
.prev-btn-container,
.next-btn-container {
height: 8vh;
width: 8vh;
}
button {
font-size: 10vh;
padding-bottom: 1.25vh;
}
.img-nav-container {
height: 4vh;
top: calc(50% + 33vh);
}
.img-nav-item {
width: 4vh;
}
.img-nav-item:not(:last-child) {
margin-right: 0.5vh;
}
.inner-circle {
width: 2vh;
height: 2vh;
border: 0.5vh solid white;
}
.outer-circle {
width: 3.5vh;
height: 3.5vh;
}
.img-nav-item:hover > .outer-circle {
width: 3.75vh;
height: 3.75vh;
}
/* override */
.img-nav-item-selected:hover > .outer-circle {
width: 3.5vh;
height: 3.5vh;
}
}
JavaScript
const images = document.querySelectorAll('img')
const totalImages = images.length;
const prevBtn = document.querySelector('.prev-btn')
const nextBtn = document.querySelector('.next-btn')
const selectedImgBtns = document.querySelectorAll('.img-nav-item')
let currentImgId = 0;
const hideAllImages = () => {
images.forEach(img => {
// hide all images
if (img.classList[0] === 'visible') {
img.classList.remove('visible')
img.classList.add('hidden')
}
})
}
const traverseImages = (direction) => {
hideAllImages()
if (direction === 'prev') {
currentImgId = currentImgId ? (currentImgId - 1) % totalImages : totalImages - 1
} else {
currentImgId = (currentImgId + 1) % totalImages
}
images[currentImgId].classList.remove('hidden')
images[currentImgId].classList.add('visible')
selectedImgBtns.forEach(btn => btn.classList.remove('img-nav-item-selected'))
selectedImgBtns[currentImgId].classList.add('img-nav-item-selected')
}
const handleBtnClick = (btn, i) => {
// not sure about this fuckery, but it works
if (btn.classList.forEach(btnClass => {
if (btnClass === 'img-nav-item-selected') {
return true
}
})) {
return
}
selectedImgBtns.forEach(btn => btn.classList.remove('img-nav-item-selected'))
btn.classList.add('img-nav-item-selected')
hideAllImages()
currentImgId = i
images[currentImgId].classList.remove('hidden')
images[currentImgId].classList.add('visible')
}
prevBtn.addEventListener('click', () => traverseImages('prev'))
nextBtn.addEventListener('click', () => traverseImages('next'))
selectedImgBtns.forEach((btn, i) => {
btn.addEventListener('click', () => handleBtnClick(btn, i))
})