Embla Carousel Documentation

website·Indexed 35 days ago

https://www.embla-carousel.com/

A high-performance carousel library featuring minimal DOM manipulation. Includes guides for setup, slide sizing, and alignments, as well as API references for methods, options, and events. Supports integration with React, Vue, Svelte, and Solid, and offers official plugins for Autoplay, Auto Scroll, Auto Height, Fade, Class Names, and Wheel Gestures. Documentation available for v8 and v9.0.0-rc03.

Tokens
29.7K
Snippets
175
Records
185
Agent score
70%

What's inside Embla Carousel

  1. Understand Embla Carousel DOM manipulation

    Embla Carousel uses minimal DOM manipulation to ensure high performance. It does not encapsulate or wrap your elements, meaning you retain full control over your markup. The library only modifies the DOM in two ways using inline translate3d transforms:

    1. Carousel container: Applies translate3d to create the scrolling effect.
    2. Carousel slides: Applies translate3d to adjust positions, specifically for looping functionality.

    Note: While the core library and framework wrappers follow this minimal approach, individual plugins may modify the DOM further.

    <div class="embla">
      <div class="embla__viewport">
        <!-- The container receives an inline transform for scrolling -->
        <div class="embla__container" style="transform: translate3d(73.5px, 0px, 0px)">
          <!-- Slides may also receive inline transforms for looping -->
          <div class="embla__slide" style="transform: translate3d(0px, 0px, 0px)">
            <span>1</span>
          </div>
        </div>
      </div>
    </div>
  2. Understand Embla Carousel DOM manipulation

    v8

    Embla Carousel achieves high-performance scrolling by using minimal DOM manipulation. It does not wrap or encapsulate your elements, meaning you retain full control over your markup. The core library only modifies the DOM in two ways using inline translate3d transforms:

    1. Carousel container: Applies translate3d to create the overall scroll effect.
    2. Carousel slides: Applies translate3d to adjust positions, specifically used for looping functionality.

    Note that while the core library is minimal, individual plugins may modify the DOM further.

    <div class="embla">
      <div class="embla__viewport">
        <!-- The container receives an inline transform for scrolling -->
        <div class="embla__container" style="transform: translate3d(73.5px, 0px, 0px)">
          <!-- Slides may also receive inline transforms for looping -->
          <div class="embla__slide" style="transform: translate3d(0px, 0px, 0px)">
            Slide 1
          </div>
        </div>
      </div>
    </div>
  3. Understand how Embla Carousel handles slide sizes

    v8
    Embla Carousel does not assign slide sizes itself. Instead, it measures the computed dimensions of the slides resulting from your CSS and uses those values to calculate scrolling. This allows developers to use any CSS unit, mix different sizes for variable-width slides, and use any layout method (flexbox, grid, etc.) as long as slides stack along the carousel's scroll axis (horizontally for horizontal carousels, vertically for vertical carousels).
  4. Update Embla Carousel options after initialization

    v8
    To change configuration options after the carousel has been initialized, use the reInit method. In framework wrappers (React, Vue, Solid, Svelte), providing reactive options will trigger this reinitialization automatically.
    import EmblaCarousel from 'embla-carousel'
    
    const wrapperNode = document.querySelector('.embla')
    const viewportNode = wrapperNode.querySelector('.embla__viewport')
    
    let loopEnabled = true
    const emblaApi = EmblaCarousel(viewportNode, { loop: loopEnabled })
    
    function toggleLoop() {
      loopEnabled = !loopEnabled
      // Update options and reinitialize
      emblaApi.reInit({ loop: loopEnabled })
    }
  5. Register carousel controls for accessibility

    To apply ARIA attributes and labels to carousel controls, you must register them using the plugin's setup methods. You can provide either a DOM element or a CSS selector string.
    const accessibility = emblaApi.plugins().accessibility;
    
    // Register previous and next buttons
    accessibility?.setupPrevAndNextButtons('.embla__prev-button', '.embla__next-button');
    
    // Register dot buttons wrapper
    accessibility?.setupDotButtons('.embla__dots');
    
    // Register the live region element for announcements
    accessibility?.setupLiveRegion('.embla__live-region');
  6. Set up the HTML structure for Embla Carousel

    v8
    Embla Carousel requires a specific hierarchy: an optional outer wrapper, a viewport (which acts as the overflow wrapper), and a container that holds the individual slides. Navigation buttons should be placed outside the viewport to avoid drag conflicts.
    <div class="embla">
      <div class="embla__viewport">
        <div class="embla__container">
          <div class="embla__slide">Slide 1</div>
          <div class="embla__slide">Slide 2</div>
          <div class="embla__slide">Slide 3</div>
        </div>
      </div>
      <button class="embla__prev">Scroll to prev</button>
      <button class="embla__next">Scroll to next</button>
    </div>
  7. Implement dot navigation buttons in Embla Carousel

    To create dot buttons for carousel navigation, use the snapList() method to determine the total number of snap points (slide groups) and the goTo(index) method to scroll to a specific snap index when a button is clicked. To ensure a responsive experience, re-initialize the buttons on the reinit event.
    import EmblaCarousel from 'embla-carousel'
    
    const wrapperNode = document.querySelector('.embla')
    const viewportNode = wrapperNode.querySelector('.embla__viewport')
    const dotsNode = wrapperNode.querySelector('.embla__dots')
    const emblaApi = EmblaCarousel(viewportNode, { loop: false })
    
    const createDotButtonHtml = (emblaApi, dotsNode) => {
      const dotTemplate = document.getElementById('embla-dot-template')
      const snapList = emblaApi.snapList()
      // Generate a button for each snap point
      dotsNode.innerHTML = snapList.reduce((acc) => acc + dotTemplate.innerHTML, '')
      return Array.from(dotsNode.querySelectorAll('.embla__dot'))
    }
    
    const addDotButtonClickHandlers = (emblaApi, dotNodes) => {
      dotNodes.forEach((dotNode, index) => {
        dotNode.addEventListener('click', () => emblaApi.goTo(index), false)
      })
    }
    
    const createAndSetupDotButtons = (emblaApi, dotsNode) => {
      const dotNodes = createDotButtonHtml(emblaApi, dotsNode)
      addDotButtonClickHandlers(emblaApi, dotNodes)
    }
    
    // Initial setup
    createAndSetupDotButtons(emblaApi, dotsNode)
    
    // Update buttons if the carousel re-initializes
    emblaApi.on('reinit', () => createAndSetupDotButtons(emblaApi, dotsNode))
    <div class="embla">
      <div class="embla__viewport">
        <div class="embla__container">
          <div class="embla__slide">Slide 1</div>
          <div class="embla__slide">Slide 2</div>
          <div class="embla__slide">Slide 3</div>
        </div>
      </div>
      <!-- Container for the dots -->
      <div class="embla__dots"></div>
      
      <!-- Template for the dot buttons -->
      <script type="text/template" id="embla-dot-template">
        <button class="embla__dot">
          <!-- Button content -->
        </button>
      </script>
    </div>
  8. Install Embla Carousel for Svelte

    v8
    Install the embla-carousel-svelte package to integrate Embla Carousel into a Svelte project. This wrapper ensures seamless integration and automatic cleanup when the component is unmounted.
    npm install embla-carousel-svelte --save
  9. Add plugins to Embla Carousel in Solid

    v8
    Plugins are added by passing an optional plugin array as the second argument to the useEmblaCarousel primitive. To interact with a plugin (like Autoplay) after the API is initialized, use Solid's createEffect and on to monitor the emblaApi signal.
    import { createEffect, on } from 'solid-js'
    import useEmblaCarousel from 'embla-carousel-solid'
    import Autoplay from 'embla-carousel-autoplay'
    
    export function EmblaCarousel() {
      const [emblaRef, emblaApi] = useEmblaCarousel(
        () => ({ loop: false }),
        () => [Autoplay()]
      )
    
      createEffect(
        on(emblaApi, (api) => {
          if (!api) return
          api.plugins().autoplay?.play()
        })
      )
    
      return (
        <div class="embla">
          <div class="embla__viewport" ref={emblaRef}>
            <div class="embla__container">
              <div class="embla__slide">Slide 1</div>
              <div class="embla__slide">Slide 2</div>
              <div class="embla__slide">Slide 3</div>
            </div>
          </div>
        </div>
      )
    }
  10. Install Embla Carousel SSR plugin

    The embla-carousel-ssr plugin enables server-side rendering support for Embla Carousel. It generates stable CSS transforms before browser dimensions are available, which prevents layout shifts during hydration.
    npm install embla-carousel-ssr --save
  11. Implement the required HTML structure for Embla Carousel

    v8
    Embla Carousel requires a specific three-level hierarchy to function correctly: a viewport element that hides overflow, a scroll container that holds the slides, and the individual slide elements themselves. While the outer wrapper is optional, the viewport → container → slides relationship is mandatory. You may use any semantic elements (e.g., <section>, <article>) instead of <div>.
    <div class="embla">
      <div class="embla__viewport">
        <div class="embla__container">
          <div class="embla__slide">Slide 1</div>
          <div class="embla__slide">Slide 2</div>
          <div class="embla__slide">Slide 3</div>
        </div>
      </div>
    </div>