Slick
Slick Carousel creates a carousel around jQuery-managed markup, cloned slides, option objects, generated controls, and event callbacks. React Slick wraps the same model in React components.
Blossom keeps the carousel as a native scroll container. Layout, slide sizing, gaps, breakpoints, and snapping belong in CSS, while Blossom adds dragging and small convenience methods.
Migration mindset
When moving from Slick Carousel to Blossom, migrate the carousel in three steps:
- Replace Slick's generated track/list structure with a single
<BlossomCarousel>root and direct children. - Move Slick options such as
slidesToShow,slidesToScroll,centerMode, andresponsiveinto CSS. - Replace Slick method calls and events with Blossom methods, native scroll APIs, and browser observers.
Installation
Remove Slick packages and install the matching Blossom package for your framework.
npm uninstall vue-slick-carousel slick-carousel
npm install @blossom-carousel/vue
npm uninstall react-slick slick-carousel
npm install @blossom-carousel/react
npm uninstall slick-carousel jquery
npm install @blossom-carousel/svelte
npm uninstall slick-carousel jquery
npm install @blossom-carousel/core
Import Blossom's core stylesheet once in your app.
import "@blossom-carousel/core/style.css";
Component structure
Slick and React Slick wrap your slides in a generated list and track. Blossom uses one scroll container with direct slide children.
<script setup lang="ts">
import VueSlickCarousel from "vue-slick-carousel";import "vue-slick-carousel/dist/vue-slick-carousel.css";import { BlossomCarousel } from "@blossom-carousel/vue";import "@blossom-carousel/core/style.css";
const slickSettings = { slidesToShow: 4, slidesToScroll: 1 };</script>
<template>
<VueSlickCarousel v-bind="slickSettings"> <div>Slide 1</div> <div>Slide 2</div> <div>Slide 3</div> </VueSlickCarousel> <BlossomCarousel class="carousel grid! grid-auto-cols grid-cols-[calc((100% - 3rem) / 4)] gap-4"> <div class="slide snap-start">Slide 1</div> <div class="slide snap-start">Slide 2</div> <div class="slide snap-start">Slide 3</div> </BlossomCarousel></template>
import Slider from "react-slick";import "slick-carousel/slick/slick.css";import { BlossomCarousel } from "@blossom-carousel/react";import "@blossom-carousel/core/style.css";
export function Carousel() {
return (
<Slider slidesToShow={4} slidesToScroll={1}> <div>Slide 1</div> <div>Slide 2</div> <div>Slide 3</div> </Slider> <BlossomCarousel className="carousel grid! grid-auto-cols grid-cols-[calc((100% - 3rem) / 4)] gap-4"> <div className="slide snap-start">Slide 1</div> <div className="slide snap-start">Slide 2</div> <div className="slide snap-start">Slide 3</div> </BlossomCarousel> );
}
<script>
import { onMount } from "svelte"; import $ from "jquery"; import "slick-carousel"; import "slick-carousel/slick/slick.css"; import BlossomCarousel from "@blossom-carousel/svelte"; import "@blossom-carousel/core/style.css";
let carousel;
onMount(() => { const slick = $(carousel).slick({ slidesToShow: 4, slidesToScroll: 1 }); return () => slick.slick("unslick"); });</script>
<div class="carousel" bind:this={carousel}> <div>Slide 1</div> <div>Slide 2</div> <div>Slide 3</div></div><BlossomCarousel class="carousel grid! grid-auto-cols grid-cols-[calc((100% - 3rem) / 4)] gap-4"> <div class="slide snap-start">Slide 1</div> <div class="slide snap-start">Slide 2</div> <div class="slide snap-start">Slide 3</div></BlossomCarousel><div class="carousel"> <div>Slide 1</div> <div>Slide 2</div> <div>Slide 3</div></div><blossom-carousel class="carousel grid! grid-auto-cols grid-cols-[calc((100% - 3rem) / 4)] gap-4"> <div class="slide snap-start">Slide 1</div> <div class="slide snap-start">Slide 2</div> <div class="slide snap-start">Slide 3</div></blossom-carousel>Options
Slick options describe how its track should move, clone slides, and generate UI. In Blossom, most of those choices become CSS or small browser APIs.
| Slick concept | Blossom approach |
|---|---|
slidesToShow | Use CSS grid-auto-columns to define the relative width of slides. |
slidesToScroll | Use CSS scroll-snap-align within :nth-child(xn) or nest slides in groups. |
centerMode | Use scroll-snap-align: center. |
variableWidth | Let slides size themselves with CSS. |
adaptiveHeight | Let content define height, or update layout with ResizeObserver. |
responsive | Use CSS media queries and container queries. |
infinite | Prefer bounded native scrolling, or use the experimental repeat pattern when an infinite effect is required. See Repeat example. |
draggable / swipe | Use CSS overflow: hidden on the carousel to disable dragging and scrolling. |
arrows | Use buttons that call prev() and next(). See Buttons example. |
dots | Build dots from IntersectionObserver or scrollsnapchange. See Dots example. |
For example, this Slick setup:
$(".carousel").slick({
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
responsive: [{ breakpoint: 768, settings: { slidesToShow: 3 } }],
});
becomes CSS:
.carousel {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 100%;
gap: 1rem;
scroll-snap-type: inline mandatory;
}
.slide {
scroll-snap-align: center;
}
@media (min-width: 768px) {
.carousel {
grid-auto-columns: calc((100% - 2rem) / 3);
}
}
Controls
Slick controls call methods on the Slick instance. Blossom exposes prev() and next() on the carousel element or component ref.
$(".carousel").slick("slickPrev");$(".carousel").slick("slickNext");blossom.value.prev();blossom.value.next();For direct slide navigation, use native scrolling on the target slide.
slides[index].scrollIntoView({
behavior: "smooth",
inline: "center",
block: "nearest",
});
API
Slick commonly uses afterChange to track the current slide.
With Blossom, the carousel is a real scroll container, so use browser APIs such as IntersectionObserver, scrollsnapchange, or scroll events depending on the browser support you need.
$(".carousel").on("afterChange", (_event, _slick, currentSlide) => { setSelectedIndex(currentSlide);});
carousel.addEventListener("scrollsnapchange", (event) => { setSelectedIndex(event.detail.index);});
Or use IntersectionObserver for wider browser support
const slides = Array.from(carousel.children);const observer = new IntersectionObserver( (entries) => { const activeEntry = entries.find((entry) => entry.isIntersecting); if (activeEntry) { setSelectedIndex(slides.indexOf(activeEntry.target)); } }, { root: carousel, threshold: 0.5 },);slides.forEach((slide) => observer.observe(slide));Features
Slick features usually become either small Blossom wrappers or native platform features.
| Slick feature | Blossom replacement |
|---|---|
| Arrows | Buttons that call prev() and next(). |
| Dots | Dots backed by IntersectionObserver or scrollsnapchange. |
| Autoplay | A timer that calls next() or scrolls the next slide into view. |
| Fade | CSS scroll-driven animations or intersection state. |
| Lazy load | Native loading="lazy" or framework image components. |
| Rows | CSS grid. |
| Syncing sliders | Shared selected state plus scrollIntoView(). |
Rebuild Slick features deliberately. Native scrolling often replaces more of Slick than expected.
Lifecycle
Slicks's and Blossom's lifecycle methods are similar.
$(".carousel").slick("refresh");$(".carousel").slick("unslick");blossom.init();blossom.destroy();Migration checklist
- Remove Slick packages and install the matching Blossom package.
- Import
@blossom-carousel/core/style.cssonce. - Replace Slick markup and generated track assumptions with
<BlossomCarousel>and direct slide children. - Move slide sizing, gaps, snapping, center mode, and responsive behavior into CSS.
- Replace
slickPrevandslickNextwithprev()andnext(). - Replace
slickGoTowithscrollIntoView()or nativescrollTo(). - Replace Slick events with browser observers or scroll snap events.
- Rebuild only the Slick features your carousel still needs.
Next steps
- Installation - Pick the package for your framework.
- Snapping - Configure scroll snap behavior with CSS.
- Buttons - Add previous and next controls.
- Dots - Track the active slide with browser APIs.
- Repeat - Explore an experimental repeating carousel pattern.