Carousel <l-carousel>
Carousels are used to cycle through a set of content slides in a horizontal scrollable area. Commonly used for image galleries, product showcases, and featured content. Powered by Embla Carousel.
<l-carousel>Options
Basic
Slides are <l-carousel-item> children. Set --slide-size and --slide-gap to control layout. Add drag-free for momentum scrolling.
Code
<l-carousel
drag-free
style="--slide-size: calc(100% / 3); --slide-gap: 1rem"
>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
1
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
2
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
3
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
4
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
5
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
6
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
7
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
8
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
9
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="grid place-items-center w-full text-2xl bg-gray-300"
style="height: 200px"
>
10
</div>
</l-carousel-item>
</l-carousel>Gallery
Add single for one slide at a time.
Code
<div class="p-8">
<l-carousel
class="w-[400px]"
single
style="--slide-size: 100%; --slide-gap: 0"
>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/10/1200/700"
width="400"
height="400"
style="height: 400px; max-width: none"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/11/1200/700"
width="400"
height="400"
style="height: 400px; max-width: none"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/12/1200/700"
width="400"
height="400"
style="height: 400px; max-width: none"
/>
</l-carousel-item>
</l-carousel>
</div>Dots (bar)
Add with-dots for dot navigation. Default appearance is bar. Use max-visible-dots to cap the rendered dots — edge dots shrink when more dots exist beyond the window.
Code
<l-carousel
single
with-dots
max-visible-dots="7"
>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/17/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/18/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/19/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/20/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/21/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/22/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/23/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/24/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/25/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/26/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/27/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/28/1200/700"
height="400"
/>
</l-carousel-item>
</l-carousel>Dots (circle)
Set dot-appearance="circle" for circle dots.
Code
<l-carousel
single
with-dots
dot-appearance="circle"
max-visible-dots="7"
>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/17/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/18/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/19/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/20/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/21/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/22/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/23/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/24/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/25/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/26/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/27/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/28/1200/700"
height="400"
/>
</l-carousel-item>
</l-carousel>Breakpoints
Use the breakpoints attribute (JSON) to override options at specific breakpoints. The carousel can deactivate itself at wider viewports.
Code
<style>
.carousel-breakpoints {
--slide-size: 80%;
--slide-gap: 1rem;
--button-border-color: #d3c9c9;
height: 400px;
}
@media (min-width: 768px) {
.carousel-breakpoints {
--slide-size: 33%;
--slide-gap: 1rem;
}
}
</style>
<l-carousel
class="carousel-breakpoints"
breakpoints='{"(min-width: 768px)": { "active": false }}'
>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/17/1200/700"
width="400"
height="400"
style="height: 400px"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/18/1200/700"
width="400"
height="400"
style="height: 400px"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover"
src="https://picsum.photos/id/19/1200/700"
width="400"
height="400"
style="height: 400px"
/>
</l-carousel-item>
</l-carousel>Autoplay
Set autoplay to a delay in milliseconds. Combine with axis="y" for vertical rotation.
Code
<l-carousel
axis="y"
autoplay="10000"
duration="5"
style="
--slide-height: 36px;
--button-size: 24px;
--button-bg: transparent;
--button-border-color: transparent;
--button-arrow-color: white;
"
>
<l-carousel-item>
<div
class="py-2 px-4 lg:px-8 bg-gradient-to-r from-red-600 to-red-500 text-white font-bold text-center text-sm w-full whitespace-nowrap overflow-x-auto"
>
Free shipping on orders over $80
</div>
</l-carousel-item>
<l-carousel-item>
<div
class="py-2 px-4 lg:px-8 bg-gradient-to-r from-red-600 to-red-500 text-white font-bold text-center text-sm w-full whitespace-nowrap overflow-x-auto"
>
4.9/5 (47 reviews) — Read reviews
</div>
</l-carousel-item>
</l-carousel>Examples
Product gallery
Single slide with dots and fullscreen button.
Code
<l-carousel
single
with-dots
with-fullscreen
>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/20/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/21/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/22/1200/700"
height="400"
/>
</l-carousel-item>
</l-carousel>Product grid with scrollbar
Drag-free with scrollbar and outside navigation buttons.
Code
<l-carousel
drag-free
with-scrollbar
scroll-buttons-position="outside"
style="--slide-size: calc(100% / 3); --slide-gap: 1rem"
>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/30/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/31/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/32/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/33/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/34/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/35/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/36/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/37/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/38/1200/700"
height="400"
/>
</l-carousel-item>
<l-carousel-item>
<img
class="object-cover w-full h-96"
src="https://picsum.photos/id/39/1200/700"
height="400"
/>
</l-carousel-item>
</l-carousel>Accessibility
Criteria
- Role
Each
<l-carousel-item>hasrole="group"WCAG4.1.2- Dot navigation
Dots use
role="tab"witharia-labelandaria-selectedWCAG4.1.2- Disabled buttons
Previous/next buttons are
disabledwhen at scroll boundariesWCAG4.1.2
Keyboard interactions
API reference
Importing
import 'luxen-ui/carousel';
import 'luxen-ui/carousel-item';Attributes & Properties
emblaEmblaCarouselTypePropertyautoplaynumberdefault:0Property- Choose a delay between transitions in milliseconds (default: 4000).
autoplay-optionsanyProperty- Configure autoplay options.
axisAxisOptionTypedefault:'x'Property- Choose scroll axis between x and y.
alignAlignmentOptionTypedefault:'start'Property- Align the slides relative to the carousel viewport.
breakpointsanydefault:{}Property- Breakpoint overrides for options.
loopbooleandefault:falseProperty- Enables infinite looping.
drag-freebooleandefault:falseProperty- Enables momentum scrolling (drag free).
durationnumberdefault:20Property- Set scroll duration when triggered by API methods.
skip-snapsbooleandefault:falseProperty- Allow skipping scroll snaps on vigorous drag.
slides-to-scrollSlidesToScrollOptionTypedefault:1Property- Group slides together for navigation.
start-indexnumberdefault:0Property- Set the initial scroll snap index.
contain-scrollScrollContainOptionTypedefault:'trimSnaps'Property- Clear leading and trailing empty space.
singlebooleandefault:falsePropertywith-dotsbooleandefault:falsePropertywith-scrollbarbooleandefault:falsePropertywith-fullscreenbooleandefault:falsePropertydot-appearance'circle' | 'bar'default:'bar'Propertymax-visible-dotsnumberdefault:0Property- Maximum number of dots rendered at once. When the snap count exceeds this,
a sliding window keeps the active dot in view and shrinks the edge dot(s)
on the side where dots are hidden.
0(default) renders all dots. scroll-buttons-position'inside' | 'outside'default:'inside'PropertynextPropertypreviousProperty
Methods
options()→EmblaOptionsTypeMethodgoToSlide(index: number, jump: boolean)MethodslideNodes()MethodslidesInView()MethodisActive()MethodrenderFullscreenButton()MethodrenderNextPreviousButtons()Method
Events
selectEvent- Fired when the active slide changes. Detail:
{ index: number }. slides-in-viewEvent- Fired when the set of slides in view changes. Detail:
{ indexes: number[] }. fullscreenEvent- Fired when the fullscreen button is activated.
CSS Parts
viewportPart- The carousel viewport container.
containerPart- The slides container slot.
scroll-buttonsPart- The scroll buttons wrapper.
buttonPart- Any navigation button.
button-previousPart- The previous slide navigation button.
button-nextPart- The next slide navigation button.
button-dotPart- Any dot navigation button.
dotsPart- The dots navigation wrapper.
button-fullscreenPart- The fullscreen button.
button-iconPart- Any button icon SVG.
CSS custom properties
--slide-heightCustom property- Height of slides in vertical axis mode.
--slide-sizeCustom property- Width of each slide (e.g.
100%,calc(100% / 3)). --slide-gapCustom property- Gap between slides.
--button-sizeCustom property- Size of navigation buttons.
--button-arrow-sizeCustom property- Size of arrow icons inside buttons.
--button-arrow-colorCustom property- Color of arrow icons.
--button-offsetCustom property- Offset of inside-positioned buttons from edges.
--button-border-colorCustom property- Border color of buttons.
--button-border-radiusCustom property- Border radius of buttons.
--button-bgCustom property- Background color of buttons.
--button-colorCustom property- Text/icon color of buttons.
--dot-colorCustom property- Color of inactive dots.
--dot-color-activeCustom property- Color of active dot.
--dot-marginCustom property- Margin around dots container.
--dot-edge-scaledefault:0.5Custom property- Scale factor applied to edge dots that signal more dots exist beyond the visible window ().
carousel-item CSS custom properties
--aspect-ratioCustom property- Aspect ratio of the slide.