Skip to main content

Carousel

The Carousel component displays sequential content items inside a horizontally scrolling viewport with built-in navigation arrows, pagination indicators and an optional autoplay control. Slides are provided as DhlCarouselSlide children.

The Carousel has two size variants:

  • Default — shows navigation arrows, pagination indicator and (optionally) the play button.
  • Compact — shows only the pagination indicator for a slimmer control bar.

Import

// with @dhl-official/react-library:
import { DhlCarousel, DhlCarouselSlide } from "@dhl-official/react-library"
// with @dhl-official/ui-libraries/react-library:
import { DhlCarousel, DhlCarouselSlide } from "@dhl-official/ui-libraries/react-library"

Accessibility

The Carousel is rendered as an ARIA region with the accessible name provided via the label prop. Each DhlCarouselSlide should provide its own descriptive label so screen readers can announce the slide content. Autoplay is paused automatically when the carousel receives keyboard focus or when the tab is hidden.

Notes

  • Set interval to 0 to disable autoplay entirely. In that case, the play button is hidden.
  • Set slideWidth to a value smaller than 100% (e.g. "80%") to make adjacent slides partially visible at the edges of the viewport (peek effect).
  • Use slideGap to control the spacing between slides when slideWidth is less than 100%.
  • Use the next(), previous(), goTo(index), play() and pause() methods to control the carousel programmatically.

Code

<DhlCarousel>
<DhlCarouselSlide label="First image">
<img src="/images/one.jpg" alt="" />
</DhlCarouselSlide>
<DhlCarouselSlide label="Second image">
<img src="/images/two.jpg" alt="" />
</DhlCarouselSlide>
<DhlCarouselSlide label="Third image">
<img src="/images/three.jpg" alt="" />
</DhlCarouselSlide>
</DhlCarousel>

Interactive Demo

Variants

Compact

Slim control bar that shows only the pagination indicator. Useful when the surrounding layout already provides navigation context.

<DhlCarousel size="compact">
<DhlCarouselSlide label="First image">
<img src="/images/one.jpg" alt="" />
</DhlCarouselSlide>
<DhlCarouselSlide label="Second image">
<img src="/images/two.jpg" alt="" />
</DhlCarouselSlide>
</DhlCarousel>

Peek adjacent slides

When slideWidth is less than 100%, adjacent slides become partially visible at the edges of the viewport — useful for hinting that more content is available.

<DhlCarousel slideWidth="80%">
<DhlCarouselSlide label="Product 1">
<img src="/images/one.jpg" alt="" />
</DhlCarouselSlide>
<DhlCarouselSlide label="Product 2">
<img src="/images/two.jpg" alt="" />
</DhlCarouselSlide>
<DhlCarouselSlide label="Product 3">
<img src="/images/three.jpg" alt="" />
</DhlCarouselSlide>
</DhlCarousel>

Multiple visible slides

Setting a smaller slideWidth allows several slides to appear at once. Combine with interval="0" and loop="false" for a static, card-strip layout.

<DhlCarousel slideWidth="33%" interval={0} loop={false}>
<DhlCarouselSlide label="Card 1"><div>Card 1</div></DhlCarouselSlide>
<DhlCarouselSlide label="Card 2"><div>Card 2</div></DhlCarouselSlide>
<DhlCarouselSlide label="Card 3"><div>Card 3</div></DhlCarouselSlide>
<DhlCarouselSlide label="Card 4"><div>Card 4</div></DhlCarouselSlide>
<DhlCarouselSlide label="Card 5"><div>Card 5</div></DhlCarouselSlide>
</DhlCarousel>

Without play button

Hide the autoplay toggle when the carousel should not start playback from user interaction.

<DhlCarousel showPlayButton={false}>
<DhlCarouselSlide><img src="/images/one.jpg" alt="" /></DhlCarouselSlide>
<DhlCarouselSlide><img src="/images/two.jpg" alt="" /></DhlCarouselSlide>
</DhlCarousel>

Autoplay disabled

Set interval to 0 to disable autoplay entirely. The play button is hidden when autoplay is disabled.

<DhlCarousel interval={0}>
<DhlCarouselSlide><img src="/images/one.jpg" alt="" /></DhlCarouselSlide>
<DhlCarouselSlide><img src="/images/two.jpg" alt="" /></DhlCarouselSlide>
</DhlCarousel>

Loop disabled

By default, advancing past the last slide wraps around to the first. Disable looping to make navigation stop at the boundaries.

<DhlCarousel loop={false}>
<DhlCarouselSlide><img src="/images/one.jpg" alt="" /></DhlCarouselSlide>
<DhlCarouselSlide><img src="/images/two.jpg" alt="" /></DhlCarouselSlide>
</DhlCarousel>

Use the componentOnReady() lifecycle hook and the exposed goTo(), next(), previous(), play() and pause() methods to drive the carousel from outside.

const ref = useRef(null);

useEffect(() => {
ref.current?.goTo(2);
}, []);

return (
<DhlCarousel ref={ref}>
<DhlCarouselSlide><img src="/images/one.jpg" alt="" /></DhlCarouselSlide>
<DhlCarouselSlide><img src="/images/two.jpg" alt="" /></DhlCarouselSlide>
<DhlCarouselSlide><img src="/images/three.jpg" alt="" /></DhlCarouselSlide>
</DhlCarousel>
);

Readme

Usage

Snippets of code in HTML and JavaScript to show some of the use cases for the component. The code is not meant to be executed, but to be used as a reference for the usage of the component. Angular, React and Vue usages are not included in this documentation, but can be easily derived from the html and javascript code.

default usage

<dhl-carousel>
<dhl-carousel-slide label="First image">
<img src="/images/one.jpg" alt="" />
</dhl-carousel-slide>
<dhl-carousel-slide label="Second image">
<img src="/images/two.jpg" alt="" />
</dhl-carousel-slide>
<dhl-carousel-slide label="Third image">
<img src="/images/three.jpg" alt="" />
</dhl-carousel-slide>
</dhl-carousel>

peek adjacent slides (slideWidth 80%)

When slide-width is less than 100%, adjacent slides become partially visible at the edges of the viewport.

<dhl-carousel slide-width="80%">
<dhl-carousel-slide label="Product 1">
<img src="/images/one.jpg" alt="" />
</dhl-carousel-slide>
<dhl-carousel-slide label="Product 2">
<img src="/images/two.jpg" alt="" />
</dhl-carousel-slide>
<dhl-carousel-slide label="Product 3">
<img src="/images/three.jpg" alt="" />
</dhl-carousel-slide>
</dhl-carousel>

multiple visible slides (slideWidth 33%)

Setting a smaller slide-width lets several slides appear at once.

<dhl-carousel slide-width="33%" interval="0" loop="false">
<dhl-carousel-slide label="Card 1"><div>Card 1</div></dhl-carousel-slide>
<dhl-carousel-slide label="Card 2"><div>Card 2</div></dhl-carousel-slide>
<dhl-carousel-slide label="Card 3"><div>Card 3</div></dhl-carousel-slide>
<dhl-carousel-slide label="Card 4"><div>Card 4</div></dhl-carousel-slide>
<dhl-carousel-slide label="Card 5"><div>Card 5</div></dhl-carousel-slide>
</dhl-carousel>

half-width slides (slideWidth 50%)

<dhl-carousel slide-width="50%">
<dhl-carousel-slide label="A"><div>Slide A</div></dhl-carousel-slide>
<dhl-carousel-slide label="B"><div>Slide B</div></dhl-carousel-slide>
<dhl-carousel-slide label="C"><div>Slide C</div></dhl-carousel-slide>
<dhl-carousel-slide label="D"><div>Slide D</div></dhl-carousel-slide>
</dhl-carousel>

compact size

<dhl-carousel size="compact">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/three.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

compact with peek

<dhl-carousel size="compact" slide-width="80%">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/three.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

without play button

<dhl-carousel show-play-button="false">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

custom autoplay interval

<dhl-carousel interval="3000">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

autoplay disabled

<dhl-carousel interval="0">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

loop disabled

<dhl-carousel loop="false">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>
<dhl-carousel id="my-carousel">
<dhl-carousel-slide><img src="/images/one.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/two.jpg" alt="" /></dhl-carousel-slide>
<dhl-carousel-slide><img src="/images/three.jpg" alt="" /></dhl-carousel-slide>
</dhl-carousel>

<script type="module">
const carousel = document.getElementById("my-carousel");
carousel.componentOnReady().then(async () => {
await carousel.goTo(2);
await carousel.play();
});
</script>

Properties

PropertyAttributeDescriptionTypeDefault
activeIndexactive-indexAn optional prop. The index of the currently visible slide.number0
dataClassNamedata-class-nameAn optional class name prop for the component.stringundefined
dataIddata-idAn optional prop. Gives a valid HTML ID attribute value for the component.string`dhl-carousel-${getRandomString()}`
dataTestiddata-testidAn optional prop. The test id attached to the component as a data-testid attribute.stringundefined
intervalintervalAn optional autoplay interval in milliseconds. Set to 0 to disable autoplay entirely (the play button is hidden in that case).numberDHL_CAROUSEL.DEFAULT_INTERVAL
labellabelAn optional prop. The accessible label applied to the carousel region.string"Carousel"
looploopAn optional prop. When true, advancing past the last slide wraps to the first slide and going back from the first wraps to the last. When false, navigation stops at the boundaries.booleantrue
showPlayButtonshow-play-buttonAn optional prop to show or hide the playback control button. Has no effect when size is "compact" or when interval is 0.booleantrue
sizesizeAn optional prop to select a component design variant. "default" shows arrows, pagination indicator and (optionally) the play button. "compact" shows only the pagination indicator."compact" | "default"DHL_CAROUSEL.SIZE.DEFAULT
slideGapslide-gapAn optional prop. The gap between slides as a CSS length (e.g. "16px", "1rem"). Only applies when slideWidth is less than "100%". Defaults to "0px".string"0px"
slideWidthslide-widthAn optional prop. The width of each slide as a CSS percentage (e.g. "80%", "33%"). Defaults to "100%". When less than 100%, adjacent slides become partially visible.string"100%"

Events

EventDescriptionType
dhlPlayStateChangeEmitted whenever autoplay is started or stopped.CustomEvent<{ playing: boolean; }>
dhlSlideChangeEmitted whenever the active slide changes.CustomEvent<{ index: number; previousIndex: number; }>

Methods

goTo(index: number) => Promise<void>

Jump directly to the slide at the given index.

Parameters

NameTypeDescription
indexnumber

Returns

Type: Promise<void>

next() => Promise<void>

Advance to the next slide. Wraps to the first slide when loop is enabled.

Returns

Type: Promise<void>

pause() => Promise<void>

Stop autoplay.

Returns

Type: Promise<void>

play() => Promise<void>

Start autoplay (no-op when autoplay is disabled).

Returns

Type: Promise<void>

previous() => Promise<void>

Move to the previous slide. Wraps to the last slide when loop is enabled.

Returns

Type: Promise<void>

Slots

SlotDescription
"unnamed"unnamed children slot intended for DhlCarouselSlide component(s)

Dependencies

Depends on

Graph


Built by DHL User Interface Library Team!