Build a Lightweight Carousel with CSS Scroll‑Snap and Minimal JavaScript
This article demonstrates how to replace heavy swiper libraries with a slim, pure‑CSS carousel using scroll‑snap‑type, scroll‑snap‑align, and scroll‑behavior, and adds a small JavaScript polyfill for smooth scrolling and automatic slide rotation, complete with npm packaging and compatibility notes.
Background
Traditional swiper libraries are bulky because they include many unnecessary features; the author wanted a simple scrolling effect with as little code as possible, exploring whether pure CSS effects could replace the heavy library.
Implementation Idea
scroll-snap-type makes the container automatically align to a specified element when scrolling stops, acting like an “magnet” that pulls the child into view. scroll-snap-align defines the alignment point (start, center, end) for each child element, determining where the snap occurs.
To achieve smooth scrolling, scroll-behavior: smooth adds a built‑in animation that makes the movement feel natural.
Combining these three CSS properties creates a smooth, automatic carousel. JavaScript is then used to advance the slides at intervals.
<code>.swiper-box {
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
.swiper-image {
scroll-snap-align: start;
}
setInterval(function () {
var clientWidth = ele.clientWidth;
var index = Math.floor(ele.scrollLeft / clientWidth) + 1;
if (index > imageList.length - 1) {
index = 0;
}
eleSwiperBox.scrollLeft = clientWidth * index + _ele.offsetLeft * index;
}, 3000);
</code>If a browser does not support scroll-behavior: smooth , a polyfill recursively adjusts scrollLeft in small steps until the target position is reached.
<code>if (!CSS.supports("scroll-behavior: smooth")) {
var step = function () {
var distance = scrollLeft - ele.scrollLeft;
if (Math.abs(distance) <= 3) {
ele.scrollLeft = scrollLeft;
} else {
ele.scrollLeft += distance / 4;
requestAnimationFrame(step);
}
};
step();
} else {
ele.scrollLeft = scrollLeft;
}
</code>After adding the polyfill, the carousel works across browsers, including Safari, which lacks native support for the CSS properties.
Not Only for Carousel
The same CSS properties can be used for click‑triggered smooth scrolling, providing a lightweight solution for various scrolling interactions.
Component Packaging
The code is wrapped into an npm package snap‑swiper , allowing easy installation and reuse in projects without framework constraints. It also includes lazy‑loading and error handling for images.
<code>npm i snap-swiper
import "snap-swiper/snap-swiper.css";
const snapSwiper = require("snap-swiper");
snapSwiper({
imageList: [],
el,
});
</code>References
[1] scroll‑snap‑type: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type
[2] scroll‑snap‑align: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-align
[3] scroll‑behavior: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
[4] CSS guidance: https://www.zhangxinxu.com/
[5] Code repository: https://github.com/yued-fe/snap-swiper
[6] Demo sandbox: https://codesandbox.io/s/gifted-ives-zco4l?file=/index.html
[7] GitHub source: https://github.com/yued-fe/snap-swiper
[8] CSS scroll‑snap event detection: https://www.zhangxinxu.com/wordpress/2019/04/css-scroll-snap-event-element-detect/
[9] Introduction to CSS scroll‑snap: https://www.zhangxinxu.com/wordpress/2018/11/know-css-scroll-snap/
Yuewen Frontend Team
Click follow to learn the latest frontend insights in the cultural content industry. We welcome you to join us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.