Centered & Focused
Highlight a single slide while peeking neighbors in center mode.
Unified Pointer Events
Touch, mouse, pen — one handler for all input types.
Motion Respect
prefers-reduced-motion disables animations automatically.
Accessible by Default
ARIA roles, keyboard navigation, and focus management built in.
Lazy Image Loading
Ondemand and progressive strategies for slow connections.
new Slickless("#hero-carousel", {
slidesToShow: 1,
centerMode: true,
centerPadding: "32px",
autoplay: true,
autoplaySpeed: 3200,
speed: 600,
dots: true,
arrows: false,
infinite: true,
});
Responsive Multi-Slide
Three slides on desktop, two on tablet, one on phone. Resize the browser to watch the breakpoints trigger.
new Slickless("#multi-carousel", {
slidesToShow: 3,
slidesToScroll: 1,
dots: true,
infinite: true,
responsive: [
{ breakpoint: 960, settings: { slidesToShow: 2 } },
{ breakpoint: 600, settings: { slidesToShow: 1 } },
],
});
Fade Transition
Cross-fade between full-width slides with autoplay. Pauses on hover and focus for reading comfort.
new Slickless("#fade-carousel", {
fade: true,
autoplay: true,
autoplaySpeed: 3500,
speed: 700,
dots: true,
arrows: false,
infinite: true,
});
Vertical Stack
Stacked navigation with vertical drag. Three items visible — swipe up and down.
new Slickless("#vertical-carousel", {
vertical: true,
slidesToShow: 3,
slidesToScroll: 1,
arrows: true,
infinite: true,
speed: 400,
});
Center Mode
Focused slide sits in the center while siblings peek from the sides. Drag the slider to adjust centerPadding.
new Slickless("#center-carousel", {
centerMode: true,
centerPadding: "60px",
slidesToShow: 3,
focusOnSelect: true,
infinite: true,
speed: 400,
arrows: true,
responsive: [
{ breakpoint: 720, settings: { slidesToShow: 1, centerPadding: "30px" } },
],
});
Linked Carousels
A main stage synced to a thumbnail strip. Click any thumbnail in the nav to jump the main stage.
// Initialise the nav strip first so the main stage can subscribe to it.
new Slickless("#nav-strip", {
slidesToShow: 5,
slidesToScroll: 1,
arrows: false,
focusOnSelect: true,
infinite: false,
draggable: false,
speed: 300,
});
new Slickless("#main-stage", {
slidesToShow: 1,
arrows: true,
fade: true,
asNavFor: "#nav-strip",
infinite: true,
speed: 600,
});
Custom Paging
Replace the default dot bullets with fraction indicators — or any custom element you return.
new Slickless("#custom-paging-carousel", {
slidesToShow: 1,
arrows: false,
dots: true,
speed: 500,
infinite: true,
customPaging: (i, total) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "frac-btn";
btn.setAttribute("aria-label", `Go to slide ${i + 1}`);
btn.textContent = `${String(i + 1).padStart(2, "0")} / ${String(total).padStart(2, "0")}`;
return btn;
},
});
Adaptive Height
The viewport resizes to match each slide's natural height. Toggle the switch to lock it back down.
const carousel = new Slickless("#adaptive-carousel", {
adaptiveHeight: true,
dots: true,
infinite: true,
speed: 450,
});
// Toggle the option at runtime — setOptions rebuilds the carousel.
toggle.addEventListener("change", () =>
carousel.setOptions({ adaptiveHeight: toggle.checked }));
Variable Width
Each slide keeps its own natural width — perfect for tag rails, chip lists, or mixed-aspect cards.
const carousel = new Slickless("#varwidth-carousel", {
variableWidth: true,
slidesToScroll: 1,
infinite: true,
speed: 350,
});
// Toggle the option at runtime — setOptions rebuilds the carousel.
toggle.addEventListener("change", () =>
carousel.setOptions({ variableWidth: toggle.checked }));
Lazy Image Loading
Images load only when approaching the viewport. Switch modes to see the difference — reset to reload from scratch.
<div id="lazy-carousel">
<img data-lazy="…/mountain.jpg" alt="" />
<img data-lazy="…/forest.jpg" alt="" />
… more slides
</div>
const lazy = new Slickless("#lazy-carousel", {
lazyLoad: "ondemand", // or "progressive" / false
dots: true,
infinite: false,
});
// fires for every image as it resolves
lazy.on("lazyLoaded", ({ image, src }) =>
console.log("loaded:", src));
Event System
Subscribe to lifecycle events. Swipe, click an arrow, or hit an edge — the log fills in real time.
- Ready — try the arrows or a swipe.
const carousel = new Slickless("#events-carousel", {
dots: true,
infinite: false,
speed: 400,
});
carousel.on("init", () => log("init"));
carousel.on("beforeChange", ({ currentSlide, nextSlide }) =>
log(`beforeChange: ${currentSlide} → ${nextSlide}`));
carousel.on("afterChange", ({ currentSlide }) =>
log(`afterChange: now on ${currentSlide}`));
carousel.on("swipe", ({ direction }) =>
log(`swipe: ${direction}`));
carousel.on("edge", ({ direction }) =>
log(`edge hit: ${direction}`));
// Also available as DOM events:
// carousel.root.addEventListener("slickless:afterChange", e => ...);