Слайдер как на маркетплейсах
В современных маркетплейсах и интернет-магазинах часто встречаются слайдеры, которые переключают изображения товара при наведении курсора на разные части превью.
Конечно, вариантов реализации такого слайдера очень много. Самый, наверное, простой способ — использовать готовый плагин Swiper и немножко модифицировать его pagination. Или использовать классический вариант на JavaScript, связывая картинки и кнопки по data-атрибутам или порядковым номерам.
Но я хочу разобрать, как реализовать такой эффект с помощью HTML, CSS и минимумом JavaScript.
Сделаем разметку карточки:
<ul class="catalog">
<li class="product">
<h2>Product title</h2>
<div class="gallery">
<img class="image" src="#" alt="">
<img class="image" src="#" alt="">
<img class="image" src="#" alt="">
<img class="image" src="#" alt="">
</div>
</li>
</ul>
Где ul с классом catalog это весь список товаров каталога.
Теперь нам нужны какие-то элементы, на которые будем наводить мышкой. Лучше всего, с точки зрения семантики, для этого подходят теги button. Перед каждым изображением нужно поместить свою кнопку для того, чтобы срабатывал селектор по соседним элементам вида кнопка:hover + картинка. То есть, при наведении на кнопку сделай что-то с картинкой, которая следует сразу после неё. В нашем случае, будем менять картинке прозрачность с 0 до 1 с небольшой анимацией.
Такие кнопки можно расставить руками, если карточек немного и количество картинок известно. Но я предлагаю сделать небольшой скрипт, который сделает это за нас.
const images = document.querySelectorAll(".image");
images.forEach((image) => {
// Клонируем содержимое шаблона для того, чтобы переиспользовать его несколько раз
const button = buttonTemplate.content.cloneNode(true);
// вставляем перед своим img
image.before(button);
});
<template id="buttonTemplate">
<button class="pagination-button">
<span class="visually-hidden">перейти к ... тут alt картинки</span>
</button>
</template>
Теперь можем написать стили: картинки сложим стопкой с помощью абсолютного позиционирования и сделаем прозрачными, кроме первой. Либо можно менять им z-index, а не прозрачность, тут как удобнее.
.gallery {
position: relative;
display: flex;
height: 200px;
z-index: 0;
}
.image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0;
transition: opacity 0.15s linear;
z-index: -1;
background: var(--bg-color);
/* фон на случай отвалившихся картинок */
.pagination-button:hover + &,
.gallery:not(:hover) &:nth-of-type(1) {
opacity: 1;
}
}
.pagination-button {
--pagination-color: #000000;
width: 100%;
display: block;
position: relative;
z-index: 1;
height: 100%;
border: 0;
border-bottom: 5px solid var(--pagination-color);
background: transparent;
&:hover,
.gallery:not(:hover) &:nth-of-type(1) {
--pagination-color: rgb(0, 212, 255);
}
}
Вот, что получилось:
See the pen (@Websitio) on CodePen.