Рассмотрим создание полноразмерной галереи для сайта. В первой части напишем адаптивную сетку на CSS и выведем все фотографии в виде плитки. Данная галерея подойдет почти для всех сайтов. В нее можно вывести, например, фотографии, либо свое портфолио.
Далее напишем с нуля слайдер фото на JS. Делать данный слайдер будем для сетки фотографий, которую создали в первом видео. Слайдер позволит нам вывести полноразмерное фото, а также поочередно просматривать все, что мы вывели в сетку.
Полезные ссылки
Объяснение кода можете найти в видеоуроках: часть 1, часть 2.
Стартовый проект для работы скачивайте на GitHub.
Пример работы галереи смотрите по ссылке.
HTML разметка
<!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" />
<link rel="stylesheet" href="reset.css" />
<link rel="stylesheet" href="style.css" />
<title>Adaptive gallery</title>
</head>
<body>
<div class="gallery">
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1593460354583-4224ab273cfe?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1973&q=80"
alt="BMW"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1546518071-fddcdda7580a?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1964&q=80"
alt="Mercedes"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1559416523-140ddc3d238c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2051&q=80"
alt="Toyota"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1611396058741-1d570a4fcf95?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2070&q=80"
alt="Mitsubisi"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1548536624-57fc3720f8a1?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2070&q=80"
alt="Hyndai"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1625037669052-7e033716f325?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2070&q=80"
alt="KIA"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1628711952739-0231117de73c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1931&q=80"
alt="HAVAL"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1605893477799-b99e3b8b93fe?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=1974&q=80"
alt="Ford"
/>
</div>
<div class="gallery__card">
<img
class="gallery__card__pic"
src="https://images.unsplash.com/photo-1581650107963-3e8c1f48241b?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2070&q=80"
alt="Mustang"
/>
</div>
</div>
<div class="slider">
<div class="slider__container">
<button class="slider__btn slider__btn_left">
<i class="fas fa-chevron-left"></i>
</button>
<button class="slider__btn slider__btn_right">
<i class="fas fa-chevron-right"></i>
</button>
</div>
<button class="slider__close">
<i class="far fa-times-circle"></i>
</button>
</div>
<script
src="https://kit.fontawesome.com/fce9a50d02.js"
crossorigin="anonymous"
></script>
<script src="app.js"></script>
</body>
</html>
CSS стили
.gallery {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
}
.gallery__card {
position: relative;
height: 400px;
cursor: pointer;
overflow: hidden;
}
.gallery__card__pic {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
transition: 0.2s;
}
.gallery__card:hover .gallery__card__pic {
transform: scale(1.1);
}
.slider {
opacity: 0;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
pointer-events: none;
}
.active {
opacity: 1;
pointer-events: all;
}
.slider__container {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
width: 80vw;
height: 80vh;
}
.slider__btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
padding: 20px;
font-size: 30px;
z-index: 10;
}
.slider__btn_left {
left: 25px;
}
.slider__btn_right {
right: 25px;
}
.slider__close {
position: absolute;
right: 0;
top: 0;
font-size: 30px;
padding: 20px;
color: #fff;
background: none;
border: none;
}
JS скрипт
const cards = Array.from(document.querySelectorAll(".gallery__card"));
const slider = document.querySelector(".slider");
const sliderContainer = document.querySelector(".slider__container");
const picture = Array.from(document.querySelectorAll(".gallery__card__pic"));
const sliderBtnLeft = document.querySelector(".slider__btn_left");
const sliderBtnRight = document.querySelector(".slider__btn_right");
const sliderClose = document.querySelector(".slider__close");
let cardIndex = -1;
let pictureFull;
for (const card of cards) {
card.addEventListener("click", (event) => {
event.preventDefault();
cardIndex = cards.indexOf(card);
pictureFull = picture[cardIndex].cloneNode();
pictureFull.style.objectFit = "contain";
sliderContainer.append(pictureFull);
slider.classList.add("active");
});
}
sliderBtnLeft.addEventListener("click", (event) => {
event.preventDefault();
changePicture("left");
});
sliderBtnRight.addEventListener("click", (event) => {
event.preventDefault();
changePicture("right");
});
function changePicture(dir) {
if (dir === "left") {
if (cardIndex > 0) {
cardIndex--;
} else {
cardIndex = cards.length - 1;
}
} else if (dir === "right") {
if (cardIndex < cards.length - 1) {
cardIndex++;
} else {
cardIndex = 0;
}
}
let newPictureFull = picture[cardIndex].cloneNode();
newPictureFull.style.objectFit = "contain";
pictureFull.replaceWith(newPictureFull);
pictureFull = newPictureFull;
}
sliderClose.addEventListener("click", (event) => {
event.preventDefault();
slider.classList.remove("active");
pictureFull.remove();
newPictureFull.remove();
});