I'm working on attempting to replicate this gallery: https://preview.themeforest.net/item/core-minimalist-photography-portfolio/full_screen_preview/240185
I have some code that works for me on my desktop, giving a similar effect only displaying 3 images at a time, but it is not responsive. I'd like for it to adjust as the example, cropping down to only displaying the middle image when the viewport is small enough. I thought the percentages would work but it doesn't adjust to the view port at all and maintains its size regardless of the window size. I'd like it to be compatible with Bootstrap, but I'm not sure if Bootstrap is interfering with any of my attempts to make this responsive or not.
This is my HTML:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1">
<title>Horizontal Scroll Gallery</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<nav class="navbar navbar-expand-lg bg-body-tertiary rounded" aria-label="Thirteenth navbar example">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample11" aria-controls="navbarsExample11" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse d-lg-flex" id="navbarsExample11">
<a class="navbar-brand col-lg-3 me-0" href="#">Brand</a>
<ul class="navbar-nav col-lg-6 justify-content-lg-center">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">Disabled</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
</ul>
<div class="d-lg-flex col-lg-3 justify-content-lg-end">
<button class="btn btn-primary">CTA</button>
</div>
</div>
</div>
</nav>
</head>
<body>
<div class="container-fluid ps-3 pe-3">
<div class="gallery-container">
<div class="gallery">
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-seine-boat.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-seine-boat.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/notre-dame-river-boat.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/paris-cafe-terrace.jpg" alt="">
</div>
</div>
<div class ="units">
<div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
<div >
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/74321/shop-window-reflection.jpg" alt="">
</div>
</div>
</div>
</div>
</div>
Here is my CSS:
.gallery-container {
overflow: hidden;
position: relative;
width:100%;
}
.gallery {
display: flex;
width:max-content;
transition: transform 1s cubic-bezier(0.25, 1, 0.5, 1);
}
.gallery img {
height: 37rem;
width:100%;
object-fit: cover;
transition: transform 0.8s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.8s ease-in-out;
flex: 0 0 auto;
opacity: 0.6;
padding: 3rem;
}
.gallery img.active {
transform: scale(1.2);
opacity: 1;
scroll-snap-align: center;
flex: none;
}
/*Reflected CSS */
/* reflection */
.units > :last-child {
transform: rotatex(180deg) translatey(2.95rem);
mask-image: linear-gradient(transparent 30%, white 90%);
-webkit-mask-image: linear-gradient(transparent 30%, white 90%);
text-shadow: 0 0 8px rgba(255 0 0 / 0.4), -2px -2px 6px rgba(0 255 0 / 0.4),
2px 2px 4px rgba(0 255 255 / 0.4);
background-image: unset;
}
/* original design */
.units > * {
font: bolder 5rem/5rem "EB Garamond";
background-image: url();
background-clip: text;
-webkit-background-clip: text;
color: transparent;
}
.units {
width: max-content;
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
pointer-events: none;
padding: 0;
margin:0;
display: inline-block;
}
My javscript:
const gallery = document.querySelector('.gallery');
const images = document.querySelectorAll('.gallery img');
let index = 0;
let imageCounter = 2;
let imageWidth;
const galleryContainer = document.querySelector('.gallery-container');
// Function to update the gallery when the window is resized or when the wheel is scrolled
function updateGallery() {
// Ensure the width is calculated correctly based on the container's width
imageWidth = galleryContainer.offsetWidth / 6;
// Apply a smooth translate effect to the gallery
gallery.style.transform = `translateX(${-index * imageWidth}px)`;
// Update active class on the images (based on scroll position)
images.forEach(img => img.classList.remove('active'));
images[imageCounter].classList.add('active');
}
// Event listener for wheel scroll
document.addEventListener('wheel', (event) => {
if (event.deltaY > 0 && index < images.length - 6) { // Scroll down
index += 2;
imageCounter += 2;
} else if (event.deltaY < 0 && index > 0) { // Scroll up
index -= 2;
imageCounter -= 2;
}
updateGallery();
});