Skip to main content
Design system

Carousel

A carousel is a type of UI pattern that displays several content items in a linear sequence. Carousels can accommodate various kinds of content including text, images, and media. A carousel often includes visual navigation (such as buttons, arrows, or chevrons) to indicate the component is interactive and can be controlled directly by the user. The minimum number of items in a carousel is 4. Carousels are designed to contain a greater number of items than the width available -- items in the sequence that fall outside of the carousel container are hidden from view. Users can control which items are visible by clicking the "previous"/"next" buttons to navigate from left to right, or by manually swiping through the carousel.

Bundle size: 0
Install:
npm install @washingtonpost/wpds-ui-kit
|Copy
Usage:
import { Carousel } from "@washingtonpost/wpds-ui-kit"
|Copy
Storybook:  View on Storybook
Source:  View on Github

Anatomy

Note: Image not to scale

  1. Title
  2. Controls
  3. Content items
  4. Pagination Dots (index)

Options

Paging

The carousel component uses "pages" to display nested content in a linear sequence. A continuous group of visible items constitutes a page. By default, the starting page is "1". The carousel can be configured to start on a page other than "1".

Items per page

The carousel can be configured to page automatically (vased on the available width), or by a set number of items.


Guidance

Controls: Top (default)

Carousel controls are placed in the far right top corner of the component by default. This is the preferred option for most use-cases as it offers a predictable layout for users familiar with the carousel UI pattern.

Controls: Bottom

Controls can also be placed below content items, in the far right bottom corner.

Controls: Center

Controls can be positioned to overlap the content items, fixed to the far left and far right of the carousel container. This layout is suitable for use-cases in which it is preferable to maintain white space above and below the content area.

Controls on mobile devices

On mobile devices, controls are hidden by default to permit navigation by swipe only. This behavior is optimal for compact layouts such as smartphones where screen real-estate is limited.

(You may view any of the live demo examples on this page on your mobile device to see this behavior in action).

Custom controls

The carousel can accept custom "previous"/"next" buttons. However, be mindful of visual contrast and accessibility contraints when evaluating design and technical implementation.

Slideshow

The carousel component can be configured as a slideshow. The slideshow option displays one content item at a time and features automatic paging that can be toggled using the "play" / "pause" button.


Accessibility

Handling of current item

To optimize the carousel for interoperability with assistive technologies (e.g. screen -readers), make sure to refer to WAI-ARIA.

Use WAI-ARIA live-region to inform the screen-reader which item is being scrolled into view when using the previous and next buttons - this enables the content of the item to be announced by the screen-reader.

Add aria-labelledby to Carousel Items to allow the screen-reader to read the content items label when moving between them using the arrow keys

Focus

Set keyboard focus on the currently displayed item, upon user interaction with the item.

If carousel is set to page automatically, pause the animation when carousel receives keyboard focus.

Pause the animation when cursor enters hover area of carousel.

Animation / Motion

The carousel honors user preference for reduced motion by disabling animation.


API Reference

Carousel

PropDescriptionTypeDefaultRequired

CarouselRoot

PropDescriptionTypeDefaultRequired
pageControlled value for the current page
number
----False
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False
defaultPageUncontrolled value for the initial page shown
number
----False
onPageChangecallback for page change
() => void
----False
itemsPerPagenumber of items to move when the page changes @defaut auto
number | "auto"
auto False
onDescendantFocuscallback for internal focus
(id: string) => void
() => undefined False

CarouselHeader

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselHeaderContent

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselHeaderActions

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselTitle

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselPreviousButton

PropDescriptionTypeDefaultRequired
icon
"left" | "right" | "center" | "none" | ({ "@sm"?: "left" | "right" | "center" | "none"; "@md"?: "left" | "right" | "center" | "none"; "@lg"?: "left" | "right" | "center" | "none"; "@xl"?: "left" | "right" | "center" | "none"; ... 20 more ...; "@initial"?: "left" | ... 2 more ... | "none"; } & { ...; })
center False
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
CSS<{ sm: `(max-width: ${string})`; md: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; lg: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; xl: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; xxl: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; notS...
----False
variant
"cta" | "secondary" | "primary" | ({ "@sm"?: "cta" | "secondary" | "primary"; "@md"?: "cta" | "secondary" | "primary"; "@lg"?: "cta" | "secondary" | "primary"; "@xl"?: "cta" | "secondary" | "primary"; ... 20 more ...; "@initial"?: "cta" | ... 1 more ... | "primary"; } & { ...; })
primary False
density
"default" | "compact" | ({ "@sm"?: "default" | "compact"; "@md"?: "default" | "compact"; "@lg"?: "default" | "compact"; "@xl"?: "default" | "compact"; "@xxl"?: "default" | "compact"; "@notSm"?: "default" | "compact"; ... 18 more ...; "@initial"?: "default" | "compact"; } & { ...; })
compact False
isOutline
boolean | "true" | "false" | ({ "@sm"?: boolean | "true" | "false"; "@md"?: boolean | "true" | "false"; "@lg"?: boolean | "true" | "false"; "@xl"?: boolean | "true" | "false"; "@xxl"?: boolean | "true" | "false"; ... 19 more ...; "@initial"?: boolean | ... 1 more ... | "false"; } & { ...; })
----False
asChild
boolean
----False

CarouselNextButton

PropDescriptionTypeDefaultRequired
icon
"left" | "right" | "center" | "none" | ({ "@sm"?: "left" | "right" | "center" | "none"; "@md"?: "left" | "right" | "center" | "none"; "@lg"?: "left" | "right" | "center" | "none"; "@xl"?: "left" | "right" | "center" | "none"; ... 20 more ...; "@initial"?: "left" | ... 2 more ... | "none"; } & { ...; })
center False
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
CSS<{ sm: `(max-width: ${string})`; md: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; lg: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; xl: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; xxl: `(min-width: calc(${string} + 1px)) and (max-width: ${string})`; notS...
----False
variant
"cta" | "secondary" | "primary" | ({ "@sm"?: "cta" | "secondary" | "primary"; "@md"?: "cta" | "secondary" | "primary"; "@lg"?: "cta" | "secondary" | "primary"; "@xl"?: "cta" | "secondary" | "primary"; ... 20 more ...; "@initial"?: "cta" | ... 1 more ... | "primary"; } & { ...; })
primary False
density
"default" | "compact" | ({ "@sm"?: "default" | "compact"; "@md"?: "default" | "compact"; "@lg"?: "default" | "compact"; "@xl"?: "default" | "compact"; "@xxl"?: "default" | "compact"; "@notSm"?: "default" | "compact"; ... 18 more ...; "@initial"?: "default" | "compact"; } & { ...; })
compact False
isOutline
boolean | "true" | "false" | ({ "@sm"?: boolean | "true" | "false"; "@md"?: boolean | "true" | "false"; "@lg"?: boolean | "true" | "false"; "@xl"?: boolean | "true" | "false"; "@xxl"?: boolean | "true" | "false"; ... 19 more ...; "@initial"?: boolean | ... 1 more ... | "false"; } & { ...; })
----False
asChild
boolean
----False

CarouselContent

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselItem

PropDescriptionTypeDefaultRequired
id
string
----False
onKeyDown
((event: KeyboardEvent<HTMLDivElement>) => void) & KeyboardEventHandler<HTMLDivElement>
----False
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False
focused
boolean | "true" | "false" | ({ "@sm"?: boolean | "true" | "false"; "@md"?: boolean | "true" | "false"; "@lg"?: boolean | "true" | "false"; "@xl"?: boolean | "true" | "false"; "@xxl"?: boolean | "true" | "false"; ... 19 more ...; "@initial"?: boolean | ... 1 more ... | "false"; } & { ...; })
----False
index
number
----False
itemsShownPerPage
number
----False

CarouselFooter

PropDescriptionTypeDefaultRequired
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
{} & { alignContent?: AlignContent | Globals | ScaleValue | Index; alignItems?: AlignItems | Globals | ScaleValue | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; }
----False

CarouselDots

PropDescriptionTypeDefaultRequired
labelThe input's label text, required for accessibility
string
Pagination Dots False
cssWPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides.
CSS
----False
unitNameSpecifies the type of element represented by the dots (e.g., "Page")
string
----False
orientationIf the dots are oriented left to right or top to bottom
"horizontal" | "vertical"
----False

useActiveDescendant

PropDescriptionTypeDefaultRequired
Edit this page on GitHub.