1

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();
});

1 Answer 1

0

The main issue seems to be that your layout isn’t fully responsive because you're using fixed structures like max-content, large paddings, and hardcoded values in your JS. Instead, I’d recommend using a flexbox layout with overflow-x set to auto on your gallery container to enable horizontal scrolling that adjusts naturally to the screen size.

Some Key fixes can include:

  1. Use horizontal scrolling with “overflow-x:auto” and Flexbox - allowing the gallery to adjust naturally based on screen size.
css:
   .gallery-container {
     display: flex;
     overflow-x: auto;
     scroll-snap-type: x mandatory;
     -webkit-overflow-scrolling: touch;
   }

   .gallery {
     display: flex;
     flex-wrap: nowrap;
   }

   .gallery img {
     flex: 0 0 auto;
     width: 100vw; 
     object-fit: cover;
     scroll-snap-align: center;
   }


  1. Now on JS, rather than dividing the container width by a fixed number like 6, use images[0].clientWidth to get the actual image width dynamically. That way, the scrolling behaviour will work properly no matter the screen size or how many images are visible
const imageWidth = images[0].clientWidth;
gallery.style.transform = `translateX(${-index * imageWidth}px)`;

You can also add a Bootstrap container and row classes if needed but you need to make sure they don’t override the scrolling behaviour

  • On large screens it should set the image width to show 3 images and on smaller screens it should centre 1- (width: 100vw; - Or 33.33vw for 3 at a time )

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.