Blossom Carousel Logo
GitHub
Framework Guides

Web Components

Use Blossom Carousel as a framework-free custom element with package imports or a CDN build.

Install

pnpm add @blossom-carousel/web

Module setup

import "@blossom-carousel/web";
import "@blossom-carousel/web/style.css";

After the module is imported, the <blossom-carousel> element is registered.

<blossom-carousel class="carousel">
  <div class="slide">Slide 1</div>
  <div class="slide">Slide 2</div>
  <div class="slide">Slide 3</div>
</blossom-carousel>

CDN setup

<script
  defer
  src="https://unpkg.com/@blossom-carousel/web/dist/blossom-carousel-web.umd.js"
></script>
<link
  rel="stylesheet"
  href="https://unpkg.com/@blossom-carousel/web/dist/blossom-carousel-web.css"
/>

Use the CDN build for static pages without a build step.

Place previous, next, and dot controls outside the carousel with <blossom-prev>, <blossom-next>, and <blossom-dots>. Link them to the carousel with an id on <blossom-carousel>, and a matching for attribute on each control and mark slides with data-blossom-slide.

<blossom-carousel id="my-carousel">
  <div data-blossom-slide>Slide 1</div>
  <div data-blossom-slide>Slide 2</div>
  <div data-blossom-slide>Slide 3</div>
  ...
</blossom-carousel>

<blossom-prev for="my-carousel"></blossom-prev>
<blossom-dots for="my-carousel"></blossom-dots>
<blossom-next for="my-carousel"></blossom-next>

Prev/Next Buttons

<blossom-prev> and <blossom-next> are aware of configured scroll-snap and will navigate between snap points. When no scroll-snap is configured, they will slide the carousel proportionally.

Slot your own content to replace the default button icon.

<blossom-prev for="my-carousel">
  <span>Previous</span>
</blossom-prev>

Dots

<blossom-dots> renders one button per slide marked with data-blossom-slide. Default styles can be themed with CSS custom properties on the component or any ancestor:

/* defaults */
{
  --blossom-dot-size: 0.625rem;
  --blossom-dot-radius: 50%;
  --blossom-dot-color: currentColor;
  --blossom-dot-opacity: 0.35;
  --blossom-dot-hover-opacity: 0.6;
  --blossom-dot-active-opacity: 1;
}

To bring your own dots, provide a <blossom-dot> child — it is cloned for each slide and its inner <button> receives navigation attributes automatically.

<blossom-dots for="my-carousel">
  <blossom-dot class="my-dot">
    <button type="button" aria-label="Custom label"></button>
  </blossom-dot>
</blossom-dots>

Or let blossom-dot create the button from its light-DOM children:

<blossom-dots for="my-carousel">
  <blossom-dot class="my-dot"></blossom-dot>
</blossom-dots>

The prototype <blossom-dot> stays hidden; clones are rendered in the dots container. Existing aria-label and other attributes on your button are preserved. Since it's a single cloned template, every dot gets identical content — fine for a single active/inactive look, but not for content that varies per slide (e.g. per-slide thumbnails).

For that, set renderDot on the blossom-dots element — a callback invoked once per slide with (index, active, forId). It takes priority over any <blossom-dot> prototype and returns the element to render; navigation attributes are merged onto its <button> automatically:

<blossom-dots for="my-carousel" id="dots"></blossom-dots>

<script type="module">
  document.getElementById("dots").renderDot = (index, active) => {
    const button = document.createElement("button");
    button.setAttribute("data-blossom-dot", "");
    button.className = "dot";
    button.dataset.active = String(active);
    button.innerHTML = `<img src="/thumbs/${index}.jpg" alt="Slide ${index + 1}">`;
    return button;
  };
</script>

See the Buttons and Dots examples for live demos.

Listening for commands

Listen for command events on the carousel to know when any navigation control is triggered:

  • previous (--blossom-prev)
  • next (--blossom-next)
  • dot (--blossom-goto-{index}).

These events are not fired by drag or free scrolling. Read event.command (or event.detail.command where the Invoker Commands polyfill applies).

<blossom-carousel id="my-carousel">
  <div data-blossom-slide>Slide 1</div>
  <div data-blossom-slide>Slide 2</div>
  <div data-blossom-slide>Slide 3</div>
</blossom-carousel>

<script>
  document
    .getElementById("my-carousel")
    .addEventListener("command", (event) => {
      const command = event?.command || event?.detail?.command;
    });
</script>

Overscroll API

Tap into Blossom's drag engine's overscroll behavior to create your own style.

<blossom-carousel id="my-carousel">
  <div>Slide 1</div>
  <div>Slide 2</div>
  <div>Slide 3</div>
</blossom-carousel>

<script>
  document
    .getElementById("my-carousel")
    .addEventListener("overscroll", (event) => {
      event.preventDefault();
      const overScroll = event.detail.left;

      Array.from(event.currentTarget.children).forEach((slide) => {
        slide.style.transform = `scale(${1 - overScroll * 0.1})`;
      });
    });
</script>