Horizontal Scrolling Slider using CSS Scroll Snapping and JavaScript

By: on Feb 3, 2025

Sliders have evolved over the years, from traditional carousels to sleek, scroll-based designs. While classic carousels still have their place, modern UI trends often favor a more seamless, interactive experience.

In this tutorial, we’ll build a horizontal scrolling slider inspired by the MS Reimagine UI, where cards extend off the page and scroll smoothly.

Features of Our Slider

  • Horizontal scrolling with smooth transitions.
  • Cards extend off the page for a sleek look.
  • Navigation buttons for scrolling left and right.
  • Accessible and mobile-friendly.

Let’s dive in!

1
2
3
4
5
6
7
8

1. HTML Structure

We’ll start with a simple layout containing a slider container, a scrollable slider track, and cards inside it

<div class="slider-container">
<button class="prev-btn" aria-label="Previous">&#9665;</button>
<div class="slider">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
</div>
<button class="next-btn" aria-label="Next">&#9655;</button>
</div>

2. Styling with CSS

The key to smooth scrolling lies in CSS scroll snapping and overflow control.

/* Main Container */
.slider-container {
position: relative;
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
}

/* Slider (Horizontal Scroll) */
.slider {
display: flex;
gap: 16px;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
padding: 20px;
width: 100%;
}

/* Individual Card */
.card {
flex: 0 0 300px; /* Card width */
height: 200px;
background: linear-gradient(135deg, #6e45e2, #88d3ce);
color: white;
font-size: 2rem;
display: flex;
align-items: center;
justify-content: center;
scroll-snap-align: start;
border-radius: 10px;
}

/* Navigation Buttons */
button {
position: absolute;
top: 50%;
transform: translateY(-50%);
background: rgba(0, 0, 0, 0.5);
color: white;
border: none;
padding: 10px;
font-size: 20px;
cursor: pointer;
z-index: 10;
}

.prev-btn { left: 10px; }
.next-btn { right: 10px; }

How This Works:

  • The .slider uses scroll-snap-type: x mandatory; to snap cards into place.

  • overflow-x: auto; enables horizontal scrolling.
  • The .card elements have scroll-snap-align: start; to ensure smooth scrolling stops at each card.
  • The buttons are absolutely positioned for easy navigation.

3. Adding JavaScript for Navigation

To make the next and previous buttons functional, we’ll add some JavaScript:

document.addEventListener("DOMContentLoaded", function () {
const slider = document.querySelector(".slider");
const nextBtn = document.querySelector(".next-btn");
const prevBtn = document.querySelector(".prev-btn");

let cardWidth = document.querySelector(".card").offsetWidth + 16; // Include margin

nextBtn.addEventListener("click", () => {
slider.scrollBy({ left: cardWidth, behavior: "smooth" });
});

prevBtn.addEventListener("click", () => {
slider.scrollBy({ left: -cardWidth, behavior: "smooth" });
});
});

How This Works:

  • The nextBtn and prevBtn detect clicks.

  • scrollBy() moves the slider by the width of one card (including margin).

  • The behavior: "smooth" ensures smooth scrolling.

Final Thoughts

This JavaScript slider provides a clean, modern, and interactive way to display content in a horizontal scrolling layout. It’s lightweight, responsive, and accessible.

Possible Enhancements:

  • Autoplay: Automatically scroll through cards at intervals.

  • Infinite Loop: Clone cards to create an infinite scroll effect.

  • Pagination Dots: Add indicators for each card.

Would you like to see an infinite-scrolling version? Let me know in the comments! 🚀