Carousel
CSS + JavaScriptembla-carousel.js
A carousel built on Embla. embla-carousel.js reads
data-embla* attributes and wires the slider — drag, loop, autoplay, autoscroll,
prev/next buttons, pagination, and a current/total counter. Embla itself loads from a CDN,
so there’s nothing else to install.
<div class="embla [--slide-size:85%] sm:[--slide-size:55%]" data-embla="center" data-embla-loop data-embla-drag> <div class="embla-viewport" data-embla-viewport> <div class="embla-container"> <div class="embla-slide" data-embla-slide> <div class="flex h-40 items-center justify-center rounded-2xl bg-background-primary text-4xl font-bold text-foreground-primary" > 1 </div> </div>
<div class="embla-slide" data-embla-slide> <div class="flex h-40 items-center justify-center rounded-2xl bg-background-positive text-4xl font-bold text-foreground-positive" > 2 </div> </div>
<div class="embla-slide" data-embla-slide> <div class="flex h-40 items-center justify-center rounded-2xl bg-background-warning text-4xl font-bold text-foreground-warning" > 3 </div> </div>
<div class="embla-slide" data-embla-slide> <div class="flex h-40 items-center justify-center rounded-2xl bg-background-negative text-4xl font-bold text-foreground-negative" > 4 </div> </div> </div> </div>
<div class="mt-4 flex items-center justify-between gap-4"> <div class="flex gap-2"> <button type="button" class="button-secondary p-2" data-embla-prev aria-label="Previous"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" > <path d="M15 6l-6 6l6 6" /> </svg> </button> <button type="button" class="button-secondary p-2" data-embla-next aria-label="Next"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" > <path d="M9 6l6 6l-6 6" /> </svg> </button> </div>
<div class="flex items-center gap-2" data-embla-pagination="size-2.5 rounded-full bg-border transition-colors embla-pagination-is-selected:bg-foreground-primary cursor-pointer" ></div>
<p class="text-sm text-foreground-subtle"><span data-embla-current>1</span> / <span data-embla-total>4</span></p> </div></div>Structure
Section titled “Structure”Three nesting levels — root, viewport, container — then slides:
<div class="embla [--slide-size:85%]" data-embla="center" data-embla-loop data-embla-drag> <div class="embla-viewport" data-embla-viewport> <div class="embla-container"> <div class="embla-slide" data-embla-slide>…</div> <div class="embla-slide" data-embla-slide>…</div> </div> </div>
<button data-embla-prev>‹</button> <button data-embla-next>›</button>
<div data-embla-pagination="<dot classes>"></div> <span data-embla-current>1</span> / <span data-embla-total>2</span></div>Slides-per-view is controlled by the --slide-size variable on the root (e.g.
[--slide-size:55%]), and the gap by --gap.
Attributes
Section titled “Attributes”On the root ([data-embla])
Section titled “On the root ([data-embla])”| Attribute | Effect |
|---|---|
data-embla="start|center|end" |
Slide alignment. |
data-embla-loop |
Infinite loop. |
data-embla-drag / data-embla-drag-free |
Pointer dragging (free = momentum). |
data-embla-vertical |
Vertical axis. |
data-embla-duration |
Transition duration. |
data-embla-autoplay="<ms>" |
Auto-advance. |
data-embla-autoscroll="<speed>" + data-embla-autoscroll-direction |
Continuous scroll. |
Elements
Section titled “Elements”| Attribute | Role |
|---|---|
data-embla-viewport |
The clipping viewport (required). |
data-embla-slide |
A slide. |
data-embla-prev / data-embla-next |
Navigation buttons. |
data-embla-pagination="<classes>" |
Container; dots are generated with those classes (active dot gets is-selected). |
data-embla-current / data-embla-total |
Live index / count. |
data-embla-created |
[auto-set] [internal] processing guard. |
Style states with the variants: embla-is-snapped:, embla-is-in-view:,
embla-is-dragging:, embla-pagination-is-selected:.