How Embla Carousel Works
Embla Carousel uses minimal DOM manipulation to deliver smooth, high-performance scrolling.
Minimal DOM manipulation
Embla changes the DOM in only two ways:
- Carousel container - applies
translate3dto create the scroll effect. - Carousel slides - applies
translate3dto adjust slide positions (for looping) and improve scroll performance.
You can see this in action by inspecting the following example in your browser's developer tools:
The container receives an inline transform:
<div class="embla"> <div class="embla__viewport"> <div class="embla__container" style="transform: translate3d(73.5px, 0px, 0px)" > <!-- slides --> </div> </div></div>And slides may also receive inline transform styles:
<div class="embla__slide" style="transform: translate3d(0px, 0px, 0px)"> <div class="embla__slide__number"> <span>1</span> </div></div><div class="embla__slide" style="transform: translate3d(0px, 0px, 0px)"> <div class="embla__slide__number"> <span>2</span> </div></div>
<!-- ...and so on -->That's it — nothing else is added to the DOM. Embla does not encapsulate or wrap any elements, so you retain full control over your markup, structure, and styling. This behavior applies to the core library as well as the official framework wrappers. Plugins, however, may modify the DOM further, so check individual plugin pages for details.
Notes
Before adding custom styles, remember how Embla manipulates the DOM — applying styles incorrectly can break its functionality.
Warning: Do not apply custom transform or transition
styles directly to the carousel container or slides. Embla applies
transforms via inline styles and animates them using a spring-based system
with requestAnimationFrame; adding your own will conflict and break the
carousel's behavior.
Instead, apply transforms/transitions to a wrapper element around the carousel:
<div class="embla" style="transform: scale(0.9); transition: transform 0.3s ease"> <div class="embla__viewport"> <div class="embla__container"> <!-- slides --> </div> </div></div>When applying transforms/transitions to slides, create an inner element within each slide:
<div class="embla__slide"> <div class="embla__slide__inner" style="transform: rotate(5deg); transition: transform 0.3s ease" > <!-- slide content --> </div></div>This approach keeps Embla's animations intact while giving you full flexibility to style and animate around them.