About this snippet

Tell a better story with this horizontal scroll gallery. We made the images slide sideways as you scroll down, but it works smoothly on all screen sizes.

Size
2.7 KB
Uses
HTML, CSS, JavaScript
Loads
placehold.co
Views
197
<div class="spacer">
  <h2>Scroll Down</h2>
  <p>The gallery section will pin to the top and scroll sideways.</p>
</div>

<div class="scroll-container" id="scroll-container">
  <div class="sticky-view">
    <div class="horizontal-track" id="scroll-track">
      <div class="gallery-card">
        <img src="https://placehold.co/400x500/3b82f6/ffffff?text=One" alt="Image">
      </div>
      <div class="gallery-card">
        <img src="https://placehold.co/400x500/10b981/ffffff?text=Two" alt="Image">
      </div>
      <div class="gallery-card">
        <img src="https://placehold.co/400x500/f59e0b/ffffff?text=Three" alt="Image">
      </div>
      <div class="gallery-card">
        <img src="https://placehold.co/400x500/ef4444/ffffff?text=Four" alt="Image">
      </div>
      <div class="gallery-card">
        <img src="https://placehold.co/400x500/8b5cf6/ffffff?text=Five" alt="Image">
      </div>
    </div>
  </div>
</div>

<div class="spacer">
  <h2>Keep Scrolling</h2>
  <p>You have passed the horizontal section.</p>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #111827;
  color: #ffffff;
}

.spacer {
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.scroll-container {
  height: 400vh;
  position: relative;
}

.sticky-view {
  position: sticky;
  top: 0;
  height: 100vh;
  width: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
}

.horizontal-track {
  display: flex;
  gap: 40px;
  padding: 0 40px;
  will-change: transform;
}

.gallery-card {
  width: 350px;
  height: 500px;
  flex-shrink: 0;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
}

.gallery-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
const container = document.getElementById("scroll-container");
const track = document.getElementById("scroll-track");

window.addEventListener("scroll", function() {
  const rect = container.getBoundingClientRect();
  const top = rect.top;
  
  // Calculate total scrollable distance inside the container
  const maxScroll = rect.height - window.innerHeight;
  
  // Check if we are currently scrolling past the container
  if (top <= 0 && top >= -maxScroll) {
    const progress = -top / maxScroll;
    
    // Calculate how far the track needs to move horizontally
    const trackWidth = track.scrollWidth - window.innerWidth;
    const moveX = progress * trackWidth;
    
    track.style.transform = "translateX(-" + moveX + "px)";
  }
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save