Sliders
Horizontal Scroll Slider
Scroll through eight numbered gradient cards, or use Previous and Next to move one card at a time. The cards keep their original 300-pixel width, 200-pixel height, rounded corners, and scroll snapping.
HTML
<div data-slider>
<div data-slider-viewport tabindex="0" role="region" aria-label="Numbered gradient cards" class="slider-container position-relative w-100 flex items-center overflow-x-auto scroll-snap-x-mandatory scroll-smooth" style="scroll-padding-inline-start: calc((100vw - 1000px) / 2); scrollbar-width: none;">
<div data-slider-track class="slider flex gap-16 w-100 gap-12 p-20 margin-auto" style="max-width: 1000px;">
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">1</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">2</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">3</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">4</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">5</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">6</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">7</div>
<div data-slider-card class="card flex flex-basis-300 items-center clr-white border-r-16 snap-start justify-center" style="height: 200px; background: linear-gradient(135deg, #6e45e2, #88d3ce);">8</div>
</div>
</div>
<div class="flex gap-12 margin-auto" style="max-width: 1000px;">
<button type="button" data-slider-previous class="prev-btn cursor-pointer p-20 border-none clr-white" aria-label="Previous" style="background: rgba(0, 0, 0, 0.5);">◁</button>
<button type="button" data-slider-next class="next-btn cursor-pointer p-20 border-none clr-white" aria-label="Next" style="background: rgba(0, 0, 0, 0.5);">▷</button>
</div>
</div>
JavaScript
(() => {
function initializeSliders() {
document.querySelectorAll('[data-slider]').forEach((slider) => {
const viewport = slider.querySelector('[data-slider-viewport]');
const track = slider.querySelector('[data-slider-track]');
const card = slider.querySelector('[data-slider-card]');
const previous = slider.querySelector('[data-slider-previous]');
const next = slider.querySelector('[data-slider-next]');
if (!viewport || !track || !card || !previous || !next) return;
if (slider.dataset.sliderReady) return;
slider.dataset.sliderReady = 'true';
function move(direction) {
const gap = parseFloat(getComputedStyle(track).columnGap) || 0;
viewport.scrollBy({
left: direction * (card.getBoundingClientRect().width + gap),
behavior: 'smooth'
});
}
previous.addEventListener('click', () => move(-1));
next.addEventListener('click', () => move(1));
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeSliders, { once: true });
} else {
initializeSliders();
}
})();
Copy both the HTML and JavaScript. The controls are scoped to each data-slider wrapper. The original inline styles preserve the gradient, height, width cap, scroll padding, and button backgrounds.