Skip to Content
UX Patterns for Devs GPT is now available! Read more →

Carousel

(Also called slider, slideshow, image rotator)

Overview

A carousel is a UI component that displays a set of content or images in a rotating or sliding manner. Users can navigate through the content using arrows, dots, or swipe gestures on touch devices.

Carousels are often used to showcase featured content, promotions, or image galleries in a limited space.

Build Effort

🔴High

Requires touch/swipe support, keyboard navigation, lazy loading, auto-play controls, and proper focus management to ensure accessibility.

Use Cases

When to use:

Use a carousel when you need to display a series of related content or images in a limited space while keeping users engaged.

Common use cases include:

  • Showcasing featured products or services (e.g., homepage promotions)
  • Highlighting key messages or storytelling (e.g., step-by-step guides)
  • Displaying a portfolio of work or case studies
  • Presenting testimonials or customer reviews
  • Guiding users through a multi-step process or tutorial
  • Featuring news updates or event announcements

When not to use:

  • When the content is critical for users to see or interact with immediately
  • If the content doesn’t have a clear relationship or narrative flow
  • When users need to compare items side-by-side or view all options at once
  • If the carousel contains too many items, making navigation cumbersome
  • When the content is complex or requires significant reading time

Benefits

  • Maximizes the use of limited screen space for featuring content
  • Helps guide users through a series of related items or messages
  • Can increase engagement and time spent on a page
  • Allows for visual storytelling and brand expression
  • Provides an interactive element for users to explore

Drawbacks

  • Low engagement rates, as users often ignore or miss slides.
  • Performance-heavy, especially with large images or auto-rotation.
  • Accessibility issues, particularly for keyboard and screen reader users.
  • Not ideal for displaying critical content, as users may not interact with all slides.
  • Auto-rotation can be frustrating, especially if there is no pause control.

Anatomy

Component Structure

  1. Container
  • Wraps the carousel content and controls
  • Defines the visible area and overall dimensions of the carousel
  • Can have a border, background color, or shadow to visually separate it from other content
  1. Content Wrapper
  • Contains the individual carousel slides or items
  • Allows for smooth transitioning between slides
  • Often uses CSS transforms or absolute positioning for slide placement
  1. Slides
  • The individual content items displayed within the carousel
  • Can contain images, text, videos, or other interactive elements
  • Should have consistent dimensions and styling for a cohesive appearance
  1. Navigation Arrows
  • Allow users to manually advance or go back through the carousel slides
  • Typically placed on the left and right sides of the carousel
  • Should have clear hover and focus states for accessibility
  1. Pagination Dots
  • Indicate the total number of slides and the current active slide
  • Allow users to quickly jump to a specific slide
  • Often placed below the carousel content for easy access
  1. “See All” Link (Optional)
  • Recommended when the carousel displays a subset of a larger collection (e.g., latest articles, featured products).
  • Provides a way for users to access more related content beyond what’s shown in the carousel
  • Typically placed near the carousel, often below the slides or next to the pagination dots
  • Should have a clear and descriptive label indicating where it will take the user (e.g., “See All Products”, “View More Cases”)
  • Should be styled as a text link rather than a button to indicate navigation rather than an action.
  1. Captions (Optional)
  • Provide additional context or information about each slide
  • Can be overlaid on the slide image or placed below the slide
  • Should be concise and not obstruct the main slide content

Summary of Components

ComponentRequired?Purpose
Container✅ YesWraps the entire carousel component.
Slides Wrapper✅ YesContains all slide elements.
Slide✅ YesRepresents each individual content item.
Navigation Arrows✅ YesAllows users to move between slides.
Pagination Indicators❌ NoShows the current position within the carousel.
Autoplay Controls❌ NoAllows users to start/stop automatic slide transitions.

Best Practices

Content

Do’s ✅

  • Keep slide content focused and concise for easy scanning.
  • Use high-quality, visually compelling images that support the content message.
  • Ensure slide content is mobile-friendly and legible on smaller screens.
  • Provide meaningful alt text for slide images.
  • Keep the number of slides manageable to avoid carousel fatigue.
  • Include a “See All” link to direct users to a dedicated page with more related content (e.g., “See All Case Studies”).

Don’ts ❌

  • Don’t rely solely on the carousel to convey critical information.
  • Avoid using too much text or overly complex layouts within slides.
  • Don’t make the carousel autoplay without also providing pause/stop controls.
  • Don’t use the carousel as a primary navigation mechanism for your site.

Accessibility

Do’s ✅

  • Ensure all slide content and controls are keyboard accessible.
  • Provide ARIA labels for navigation elements and slide content.
  • Allow users to pause or stop auto-rotating carousels.
  • Give users sufficient time to read and interact with each slide.
  • Make navigation controls large enough for easy clicking or tapping.
  • Ensure the “See All” link is keyboard accessible and has a clear focus state.
  • Provide a meaningful ARIA label for the “See All” link that describes its purpose.
  • Add prefers-reduced-motion to disable animations for users with motion sensitivity.
  • Optionally, provide a “Reduce Motion” toggle for users who prefer less movement.

Don’ts ❌

  • Don’t autoplay content that contains animation or video without user consent.
  • Avoid carousel designs that trap keyboard focus within the component.
  • Don’t hide navigation controls or make them difficult to find.
  • Don’t change slide content or position while the user is interacting with it.

Visual Design

Do’s ✅

  • Use consistent design patterns and styling for all carousel elements.
  • Provide ample visual contrast for text and interactive components.
  • Ensure slide transitions are smooth and not visually jarring.
  • Use navigation indicators that clearly convey the current slide position.
  • Optimize slide images for fast loading and performance.

Don’ts ❌

  • Don’t use overly distracting transition effects that detract from the content.
  • Avoid low contrast or hard-to-read text over busy background images.
  • Don’t make the carousel unnecessarily large or overwhelming on the page.

Layout & Positioning

Do’s ✅

  • Position the carousel in a prominent location that supports its content purpose.
  • Ensure the carousel scales and adapts responsively to different screen sizes.
  • Provide ample spacing between the carousel and surrounding page elements.
  • Left-align slide content for easier reading and scanning.
  • Place navigation controls in intuitive and easy-to-reach locations.

Don’ts ❌

  • Don’t place the carousel too low on the page where users might miss it.
  • Avoid positioning the carousel in a way that obstructs other important content.
  • Don’t force users to scroll unnecessarily to view the full carousel on smaller screens.
  • Don’t overcrowd the carousel area with too many competing elements or CTAs.

Performance Optimization

Do’s ✅

  • Use lazy loading (loading="lazy") for images to reduce initial page load time.
  • Optimize carousel animations using GPU-accelerated properties (e.g., transform instead of margin).
  • Minimize reflows and repaints by ensuring smooth transitions and avoiding layout shifts.
  • Reduce event listener impact by throttling or debouncing resize and scroll events.
  • Ensure efficient resource management to prevent memory leaks and excessive CPU usage.
  • Optimize JavaScript execution by deferring non-critical scripts and avoiding blocking tasks.

Don’ts ❌

  • Don’t load off-screen images immediately—defer loading until they are about to be displayed.
  • Avoid complex animations that trigger layout recalculations (e.g., changing width or height dynamically).
  • Don’t overuse box shadows and filters, as they can slow down rendering performance.
  • Avoid large DOM structures—if the carousel contains many slides, use virtualized rendering.
  • Don’t use excessive animations that could impact performance on lower-powered devices.

Common Mistakes & Anti-Patterns

Auto-Play Without Controls

❌ What’s Wrong? Users might not have enough time to read or interact with content, and constantly rotating slides can disorient or frustrate them—especially those using assistive technologies.

How to Fix It? Always provide pause/play controls. Respect prefers-reduced-motion by disabling or slowing auto-rotation for users who prefer less animation.


No Keyboard or Touch Support

❌ What’s Wrong? Carousels often exclude users who rely on keyboard navigation or expect swipe gestures on mobile devices.

How to Fix It? Ensure you can navigate slides via Tab and arrow keys. Add swipe or drag support for mobile. Test thoroughly across various devices and accessibility tools.


Hiding Important Content in Later Slides

❌ What’s Wrong? Many users never click past the first slide, missing crucial information if it’s hidden further down the carousel.

How to Fix It? Place the most essential content in the first slide. If the content is critical, consider using a static layout or highlight it differently so users don’t need to scroll or click.


Lack of Visible Pagination

❌ What’s Wrong? Without pagination dots or numbers, users can’t tell how many slides there are or where they are within the sequence.

How to Fix It? Provide clear pagination (e.g., dots, numeric indicators) and label them properly (e.g., aria-label="Go to slide 2").


Missing or Incorrect ARIA Labels

❌ What’s Wrong? If navigation buttons and slides lack descriptive labels, screen readers can’t convey their function or content.

How to Fix It? Use attributes like aria-label="Next Slide" on arrows, role="tabpanel" for slides, and aria-roledescription="carousel" on the container. Include a descriptive aria-label (e.g., "Featured Products Carousel") so users know the carousel’s purpose.


No Clear Focus Indicator

❌ What’s Wrong? Keyboard users can lose track of where they are if there’s no visible focus outline on controls or slides.

How to Fix It? Ensure buttons, dots, or slide links have a high-contrast focus style. Test with keyboard-only navigation to confirm you never lose focus.


Inconsistent Screen Reader Announcements

❌ What’s Wrong? If slide changes aren’t announced, users with screen readers won’t realize content has updated.

How to Fix It? Use aria-live="polite" regions or update aria-hidden states so that each new slide is announced. Label slides accordingly (e.g., "Slide 2 of 5").


Overloaded Slide Content

❌ What’s Wrong? Placing too many interactive elements or large blocks of text in a single slide can overwhelm keyboard or screen reader users.

How to Fix It? Keep each slide focused and concise. If extra content is necessary, link to a dedicated page or consider an alternative layout that isn’t a carousel.

Micro-Interactions & Animations

For a carousel component, implement these specific animations to enhance user experience:

  • Slide Transition Animation:

    • Effect: Animate a smooth horizontal (or vertical) slide where the current slide moves out while the next slide slides in.
    • Timing: Aim for a 300ms transition with an ease-in-out timing function to create a natural flow.
  • Fade Transition (Optional):

    • Effect: Instead of sliding, optionally fade the outgoing slide out and the incoming slide in, offering a softer transition.
    • Timing: Use a fade duration of approximately 300ms for consistency.
  • Navigation Controls (Arrows):

    • Hover: Apply a subtle scale-up (e.g., to 1.05×) or color change when the user hovers over the arrow buttons, clearly indicating interactivity.
    • Active/Click: Trigger a brief pulse or slight scale-up effect (completing within 150–200ms) when a navigation arrow is clicked.
  • Indicator Animations:

    • Effect: For carousel indicators (e.g., dots), animate the active state by scaling the active dot slightly or changing its color to visually distinguish it from inactive indicators.
    • Timing: Keep the indicator animation brief (around 150–200ms) for immediate feedback.
  • Auto-Play & Swipe Feedback:

    • Effect: For auto-playing carousels or when swiping, ensure that transitions remain smooth and consistent. Provide a responsive drag/swipe animation with a slight resistance effect at the edges.
    • Timing: Use the same 300ms transition timing as manual navigation to maintain consistency.
  • Reduced Motion Considerations:

    • Implementation: Detect user preferences (e.g., via the prefers-reduced-motion media query) and reduce or disable these animations accordingly to ensure accessibility.

Tracking

Tracking carousel interactions helps measure engagement, detect usability issues, and optimize content placement. By capturing key user actions, we can analyze how effectively the carousel is driving interaction and whether users engage with slides beyond the first one.

Key Tracking Points

Each carousel interaction provides valuable insights into user behavior. Below are the key events that should be tracked:

Event NameDescriptionWhy Track It?
carousel.viewWhen the carousel first enters the viewport.Helps determine if users even see the carousel.
carousel.slide_changeWhen a user navigates to a different slide.Measures engagement and content interest.
carousel.auto_rotate_pauseWhen a user pauses auto-rotation (if enabled).Indicates if auto-rotation is frustrating users.
carousel.clickWhen a user clicks on a slide.Helps measure which slides attract the most attention.
carousel.swipeWhen a user swipes on mobile.Tracks touch engagement separately from clicks.
carousel.see_all_clickWhen users click the “See All” link.Indicates if users want more content than the carousel provides.

Event Payload Structure

To ensure consistent tracking, here’s a recommended event format:

{ "event": "carousel.slide_change", "properties": { "carousel_id": "homepage_featured", "slide_index": 3, "total_slides": 5, "interaction_type": "click" // or "swipe" } }

Key Metrics to Analyze

Once tracking is in place, the following metrics provide actionable insights:

  • Engagement Rate → Percentage of users who interact with the carousel.
  • Slide Completion Rate → Percentage of users who view all slides.
  • Drop-off Rate → Percentage of users who only see the first slide before leaving.
  • Click-Through Rate (CTR) → Percentage of users clicking on any slide.
  • Auto-Play Pause Rate → How often users stop auto-rotation (if enabled).

Insights & Optimization Based on Tracking

By analyzing tracking data, we can optimize the carousel experience:

  • 📉 High Drop-off Rate? → Users might not be interested in later slides. Consider making the first slides more engaging, reducing the number of slides, or testing a different pattern (e.g., a grid or tabbed interface).

  • 🔄 Frequent Auto-Play Pauses? → Users may find auto-rotation too fast or distracting. Slow down transitions, increase delay times, or disable autoplay by default.

  • 📊 Low Click-Through Rate (CTR)? → The slides might not be engaging enough. Test different visuals, headlines, and CTAs to improve interaction.

  • 📱 More Swipes than Clicks? → Mobile users may interact differently than desktop users. Optimize for touch gestures and ensure swipe responsiveness.

  • 🚀 High “See All” Click Rate? → The carousel might not be displaying enough relevant content upfront. Consider making more items visible at once or leading users to a dedicated content hub.

By continuously monitoring these metrics, we can refine the carousel’s effectiveness and improve overall user engagement.

Localization

The carousel component contains several interactive elements that require localization. This includes visible labels for buttons and controls, as well as ARIA labels for screen readers. The following JSON structure provides a comprehensive set of strings that should be translated for each supported language.

Note that for right-to-left (RTL) languages, you may need to adjust the direction of navigation arrows and content flow accordingly.

{ "carousel": { "next_slide": { "label": "Next slide", "aria_label": "Go to the next slide" }, "previous_slide": { "label": "Previous slide", "aria_label": "Go to the previous slide" }, "pause_autoplay": { "label": "Pause autoplay", "aria_label": "Pause automatic slide rotation" }, "play_autoplay": { "label": "Play autoplay", "aria_label": "Resume automatic slide rotation" }, "pagination": { "aria_label": "Slide navigation" }, "current_slide_indicator": { "aria_label": "Slide {current} of {total}" }, "see_all": { "label": "See all", "aria_label": "View all carousel items" } } }

Code Examples

Basic Implementation

The Tabbed Carousel provides a clean, tab-style navigation system where users can switch between individual content panels. This pattern is particularly effective when each slide contains detailed information that deserves focused attention.

<!-- Carousel -->
<section aria-roledescription="carousel" aria-label="Featured content">
  <!-- Visually hidden heading for screen readers -->
  <h2 class="sr-only">Featured Content Carousel</h2>

  <!-- See All link with descriptive label -->
  <a
    href="/all-products"
    class="carousel-see-all"
    aria-label="View all featured products"
  >
    See All Products
  </a>

  <!-- Controls Group -->
  <div role="group" aria-label="Carousel controls">
    <!-- Pause/Play button -->
    <button
      type="button"
      class="carousel-pause"
      aria-label="Pause auto-rotation"
      aria-pressed="false"
    >
      <span aria-hidden="true"></span>
    </button>
    <!-- Navigation controls -->
    <button type="button" class="carousel-prev" aria-label="Previous slide">
      <span aria-hidden="true">&lt;</span>
    </button>
    <button type="button" class="carousel-next" aria-label="Next slide">
      <span aria-hidden="true">&gt;</span>
    </button>

    <!-- Pagination with proper ARIA roles -->
    <div class="carousel-pagination" role="tablist" aria-label="Slide controls">
      <button
        type="button"
        id="tab1"
        role="tab"
        aria-selected="true"
        aria-controls="slide1"
      >
        <span class="sr-only">Slide 1</span>
      </button>
      <button
        type="button"
        id="tab2"
        role="tab"
        aria-selected="false"
        aria-controls="slide2"
      >
        <span class="sr-only">Slide 2</span>
      </button>
      <!-- More pagination buttons... -->
    </div>
  </div>

  <!-- Slides -->
  <div class="carousel-content">
    <div id="slide1" role="tabpanel" aria-labelledby="tab1" aria-hidden="false">
      <img src="slide1.jpg" alt="Describe what you see in the picture 1" />
      <div class="carousel-caption">Caption for slide 1</div>
    </div>
    <div id="slide2" role="tabpanel" aria-labelledby="tab2" aria-hidden="true">
      <img src="slide2.jpg" alt="Describe what you see in the picture 2" />
      <div class="carousel-caption">Caption for slide 2</div>
    </div>
    <div id="slide3" role="tabpanel" aria-labelledby="tab3" aria-hidden="true">
      <img src="slide3.jpg" alt="Describe what you see in the picture 3" />
      <div class="carousel-caption">Caption for slide 3</div>
    </div>
  </div>
</section>

The Grouped Carousel displays multiple items simultaneously, allowing users to browse through collections of related content. This implementation is ideal for showcasing product collections, image galleries, or any scenario where viewing items in groups enhances the user experience.

<!-- Carousel -->
<section aria-roledescription="carousel" aria-label="Grouped content carousel">
  <!-- Visually hidden heading for screen readers -->
  <h2 class="sr-only">Grouped Content Carousel</h2>

  <!-- See All link with descriptive label -->
  <a
    href="/all-products"
    class="carousel-see-all"
    aria-label="View all featured groups"
  >
    See All Products
  </a>

  <!-- Controls Group -->
  <div role="group" aria-label="Carousel controls">
    <!-- Pause/Play button -->
    <button
      type="button"
      class="carousel-pause"
      aria-label="Pause auto-rotation"
      aria-pressed="false"
    >
      <span aria-hidden="true"></span>
    </button>
    <!-- Navigation controls -->
    <button type="button" class="carousel-prev" aria-label="Previous group">
      <span aria-hidden="true">&lt;</span>
    </button>
    <button type="button" class="carousel-next" aria-label="Next group">
      <span aria-hidden="true">&gt;</span>
    </button>

    <!-- Pagination with proper ARIA roles -->
    <div class="carousel-pagination" role="group" aria-label="Group controls">
      <button
        type="button"
        aria-label="Show group 1 of 3"
        aria-current="true"
        aria-controls="group1"
      >
        <span class="sr-only">Group 1</span>
      </button>
      <button
        type="button"
        aria-label="Show group 2 of 3"
        aria-controls="group2"
      >
        <span class="sr-only">Group 2</span>
      </button>
      <!-- More pagination buttons... -->
    </div>
  </div>

  <!-- Grouped Slides -->
  <ul
    class="carousel-content"
    role="list"
    aria-live="polite"
    aria-atomic="true"
  >
    <li id="group1" role="group" aria-label="1 of 3">
      <div class="carousel-group">
        <img src="image1.jpg" alt="Description of image 1" />
        <img src="image2.jpg" alt="Description of image 2" />
        <img src="image3.jpg" alt="Description of image 3" />
      </div>
      <div class="carousel-caption">Caption for group 1</div>
    </li>
    <li id="group2" role="group" aria-label="2 of 3">
      <div class="carousel-group">
        <img src="image4.jpg" alt="Description of image 4" />
        <img src="image5.jpg" alt="Description of image 5" />
        <img src="image6.jpg" alt="Description of image 6" />
      </div>
      <div class="carousel-caption">Caption for group 2</div>
    </li>
    <li id="group3" role="group" aria-label="3 of 3">
      <div class="carousel-group">
        <img src="image7.jpg" alt="Description of image 7" />
        <img src="image8.jpg" alt="Description of image 8" />
        <img src="image9.jpg" alt="Description of image 9" />
      </div>
      <div class="carousel-caption">Caption for group 3</div>
    </li>
    <!-- More groups... -->
  </ul>
</section>

Accessibility

When to use a tabbed carousel vs grouped carousel?

Use a Tabbed Carousel When:

  • You have a small number of slides – Since each slide has a dedicated tab, a large number of slides can clutter the UI.
  • Users should be able to jump between slides easily – Tabs allow direct navigation to any slide without needing to cycle through sequentially.
  • Your slides contain detailed, structured content – If each slide functions as a self-contained panel (like feature descriptions, product highlights, or news sections), a tabbed interface enhances accessibility.
  • Users rely on assistive technologies – Tabs follow a clear WAI-ARIA Tabs Pattern, making them easier to navigate via screen readers and keyboard interactions.
  • You want a more structured navigation experience – Since users can visually scan and select a tab, they get a better sense of available content without guessing.

Example Use Cases for Tabbed Carousels:

  • Showcasing key product features (e.g., “Performance,” “Design,” “Battery Life”)
  • Tabbed tutorials with each step being its own slide
  • Multi-category content previews where users need to jump between different sections

Use a Grouped Carousel When:

  • Each “slide” contains multiple grouped items – This is ideal when slides are made up of sets of images or content blocks rather than a single element.
  • The focus is on scanning a collection, not individual elements – A grouped layout is better when users should browse multiple options at once.
  • You want minimal interaction but more content visible per slide – Instead of making users navigate one-by-one, grouped carousels allow them to view several options at a glance.
  • Direct navigation to specific slides isn’t a priority – Unlike tabs, grouped carousels usually rely on “previous” and “next” controls, making them better for sequential browsing.
  • Keyboard navigation and focus management should be simpler – Since each button represents a group rather than an individual tab, there are fewer interactive elements in the keyboard tab sequence, reducing accessibility complexity.

Example Use Cases for Grouped Carousels:

  • Product galleries displaying multiple related items per slide
  • Portfolio showcases with sets of images per section
  • Multi-product promotions where multiple items appear in a single frame
  • News or blog carousels where grouped articles rotate

Use the decision tree below to determine the right carousel type:

For a detailed breakdown of feature differences, refer to the table below:

FeatureTabbed CarouselGrouped Carousel
Direct NavigationUsers can pick any slide directly via tabsUsers must cycle through sequentially
Content DensityDisplays one item per slideDisplays multiple items per slide
Keyboard-FriendlyImplements full Tabs Pattern (role="tablist", role="tab", role="tabpanel")Simpler button interactions, with fewer interactive elements
Screen Reader SupportUses role=“tablist” for tab navigation and role=“tabpanel” for contentUses role=“group” for logical grouping of multiple items
Best forInteractive, information-heavy contentBrowsing collections of items

ARIA Attributes

This section outlines the required ARIA attributes for carousels, covering both Tabbed Carousels (where slides are controlled via tabs) and Grouped Carousels (where slides contain multiple items and are controlled by buttons).


General ARIA Attributes (Applicable to All Carousels)

  • Carousel container:

    • Use a <section> or role="region"*
    • aria-label for a descriptive name*
    • aria-roledescription="carousel"

    * Alternatively, use <section> with aria-labelledby to link to the carousel title.

  • Controls group:

    • role="group"
    • aria-label="Carousel controls"
  • Individual slides:

    • role="group"
    • aria-roledescription="slide"
    • aria-label for position information (e.g., "Slide 2 of 5")
  • Pause button:

    • aria-pressed="true/false" to indicate state
    • aria-label="Pause slide rotation" (or "Play slide rotation" when stopped)
  • Navigation controls (Next/Previous buttons):

    • aria-label="Next slide" and aria-label="Previous slide"
    • Avoid using only icons without labels.

ARIA Attributes for Tabbed Carousels

  • Tabs container:

    • role="tablist"
    • aria-label="Slide controls"
  • Individual tab buttons:

    • role="tab"
    • aria-selected="true/false"
    • aria-controls="tabpanel-id"
  • Slide panels (content):

    • role="tabpanel"
    • aria-labelledby="tab-id"
    • aria-hidden="true/false" (Hidden when inactive)

ARIA Attributes for Grouped Carousels

  • Slide picker controls:

    • role="group" to wrap slide selector buttons
    • aria-label="Choose slide to display"
  • Slide selector buttons:

    • role="button"
    • aria-labelledby="slide-id" (Associates button with the slide)
    • aria-disabled="true" (For currently active slide)
  • Grouped slides:

    • role="group"
    • aria-label="Slide X of Y"
    • Each contained item should have appropriate semantic tags (e.g., <article>, <figure>).

Focus Management

  1. Focus Order

The focus order should follow this sequence:

  • Pause/Play button
  • Slide controls (pagination) - can be visually placed below but should be placed in the DOM before changing the slides
  • See All link
  • Previous button
  • Slides content
  • Next button

This order ensures that users can control the carousel’s behavior before interacting with its content, with primary navigation controls (Previous/Next) taking precedence over secondary navigation (pagination).

  1. Auto-rotation Behavior

In most cases, auto-rotation is discourage as it makes more difficult for users to have a complete control over the carousel.

But if you need to support auto-rotation, here’s the expected behavior:

  • Auto-rotation must pause when:
    • Any element receives focus
    • User hovers over the carousel
    • User interacts with any control
    • Screen reader is actively reading content
  • The pause state must persist until user explicitly resumes
  • Provide clear visual indication of pause/play state
  1. Focus States
  • All interactive elements must have visible focus indicators with sufficient contrast (3:1 minimum)
  • Focus must not move automatically with slide transitions
  • Focus should remain on the control that triggered a slide change
  • Ensure focus is not trapped within the carousel

Keyboard Navigation

The carousel must be fully operable with a keyboard. Here’s the expected keyboard behavior:

KeyPurpose
Left ArrowMove to previous slide
Right ArrowMove to next slide
TabNavigate through interactive elements (navigation arrows, pagination dots, “See All” link)
Enter/SpaceActivate buttons, select slides via pagination
EscapeStop autoplay if enabled
Page Up (Optional)Move to previous slide
Page Down (Optional)Move to next slide

Note: Keys marked as optional may be omitted in some carousel implementations. The core keys (Left/Right Arrow, Tab, Enter/Space, and Escape) should always be supported for proper accessibility.

Testing Guidelines

Functional Testing

Should ✓

  • Navigate correctly between slides using arrow buttons
  • Show/hide navigation arrows appropriately at first/last slides
  • Update pagination indicators when slides change
  • Handle touch swipe gestures on mobile devices
  • Pause autoplay on hover/focus if enabled
  • Maintain slide position during window resize
  • Reset autoplay timer after manual navigation
  • Handle edge cases (single slide, empty carousel)

Accessibility Testing

Should ✓

  • Support all keyboard interactions listed in Keyboard Navigation
  • Announce slide changes to screen readers
  • Include proper ARIA labels for all controls
  • Maintain focus management during slide transitions
  • Pause autoplay when screen reader is active
  • Provide sufficient color contrast for controls
  • Include alternative text for slide images
  • Support reduced motion preferences

Visual Testing

Should ✓

  • Display smooth transitions between slides
  • Show correct active state for pagination indicators
  • Maintain aspect ratio of slide content
  • Handle different image sizes appropriately
  • Adapt layout responsively across breakpoints
  • Display loading states for lazy-loaded images
  • Show proper hover/focus states for controls
  • Maintain consistent heights during transitions

Performance Testing

Should ✓

  • Lazy load off-screen slides
  • Optimize image loading and caching
  • Maintain smooth animations (60fps)
  • Handle rapid interactions without breaking
  • Manage memory usage with many slides
  • Cleanup event listeners when destroyed
  • Function without JavaScript (graceful degradation)
  • Handle slow network conditions gracefully

Browser Support

css.properties.scroll-snap-align

chrome
Since v69
firefox
Since v68
safari
Since v11

css.properties.scroll-snap-stop

chrome
Since v75
firefox
Since v103
safari
Since v15

css.properties.overscroll-behavior

chrome
Since v63
firefox
Since v59
safari
Since v16

Design Tokens

These design tokens follow the Design Tokens Format specification and can be used with various token transformation tools to generate platform-specific variables.

{ "$schema": "https://design-tokens.org/schema.json", "carousel": { "container": { "minHeight": { "value": "400px", "type": "dimension" }, "padding": { "value": "2rem", "type": "dimension" } }, "slide": { "gap": { "value": "1rem", "type": "dimension" }, "background": { "value": "{color.gray.100}", "type": "color" } }, "seeAllLink": { "fontWeight": { "value": "600", "type": "fontWeight" }, "fontSize": { "value": "1rem", "type": "dimension" }, "color": { "default": { "value": "{color.primary.600}", "type": "color" }, "hover": { "value": "{color.primary.700}", "type": "color" } }, "marginTop": { "value": "1rem", "type": "dimension" }, "marginBottom": { "value": "1.5rem", "type": "dimension" }, "display": { "value": "inline-block", "type": "display" }, "position": { "value": "relative", "type": "position" }, "zIndex": { "value": "1", "type": "number" } }, "navigation": { "arrow": { "color": { "value": "{color.gray.700}", "type": "color" }, "background": { "default": { "value": "{color.white}", "type": "color" }, "hover": { "value": "{color.gray.200}", "type": "color" } }, "border": { "value": "none", "type": "borderStyle" }, "size": { "value": "3rem", "type": "dimension" }, "icon": { "previous": { "value": "{icon.chevronLeft}", "type": "icon" }, "next": { "value": "{icon.chevronRight}", "type": "icon" } }, "focus": { "outline": { "value": "2px solid {color.primary.600}", "type": "outline" }, "outlineOffset": { "value": "2px", "type": "dimension" } } }, "pause": { "color": { "value": "{color.gray.700}", "type": "color" }, "background": { "default": { "value": "{color.white}", "type": "color" }, "hover": { "value": "{color.gray.200}", "type": "color" }, "pressed": { "value": "{color.primary.100}", "type": "color" } }, "border": { "value": "none", "type": "borderStyle" }, "size": { "value": "2.5rem", "type": "dimension" }, "icon": { "pause": { "value": "{icon.pause}", "type": "icon" }, "play": { "value": "{icon.play}", "type": "icon" } }, "focus": { "outline": { "value": "2px solid {color.primary.600}", "type": "outline" }, "outlineOffset": { "value": "2px", "type": "dimension" } } }, "dot": { "spacing": { "value": "0.75rem", "type": "dimension" }, "size": { "default": { "value": "0.75rem", "type": "dimension" }, "active": { "value": "1rem", "type": "dimension" } }, "color": { "default": { "value": "{color.gray.300}", "type": "color" }, "active": { "value": "{color.primary.500}", "type": "color" }, "hover": { "value": "{color.primary.600}", "type": "color" } }, "border": { "radius": { "value": "50%", "type": "borderRadius" } }, "focus": { "outline": { "value": "2px solid {color.primary.600}", "type": "outline" }, "outlineOffset": { "value": "2px", "type": "dimension" } } } }, "caption": { "padding": { "value": "1rem", "type": "dimension" }, "fontSize": { "value": "1rem", "type": "dimension" }, "color": { "value": "{color.gray.700}", "type": "color" }, "background": { "value": "{color.white}", "type": "color" } }, "transition": { "duration": { "value": "600ms", "type": "duration" }, "timing": { "function": { "value": "ease-in-out", "type": "cubicBezier" } } } } }

Frequently Asked Questions

What is a carousel in web design?

A carousel is a UI component that displays multiple pieces of content in a rotating or sliding manner. It is commonly used for showcasing featured content, promotions, or image galleries in a limited space.

Are carousels effective for user engagement?

Carousels can be effective when designed thoughtfully, particularly when users actively interact with them. However, studies indicate that users often ignore them, especially if they auto-rotate or resemble advertisements. Ensuring proper controls and content prioritization can improve engagement.

What are common usability and accessibility issues with carousels?

Common issues include auto-rotation that moves too quickly, making content hard to read, lack of clear navigation controls, and poor accessibility for keyboard and screen reader users. Additionally, carousels can impact performance if not optimized with lazy loading and efficient animations.

How can I improve the accessibility of a carousel?

Ensure that all slide content and controls are keyboard accessible. Provide ARIA labels for navigation, allow users to pause or stop auto-rotation, and ensure focus is properly managed when navigating through slides. Additionally, support 'prefers-reduced-motion' for users with motion sensitivity.

Should carousels auto-rotate?

Auto-rotation can be distracting and may cause users to miss content. If used, provide controls to pause and navigate slides, set a delay of at least 5–7 seconds between transitions, and pause auto-play when a user interacts with the content.

What are the best alternatives to using carousels?

If your goal is to display structured content more effectively, consider alternatives such as a static hero section, a content grid, or prioritized sections with clear call-to-actions. Other navigation patterns like Tabs, Expandable Text, or Load More may also be more user-friendly depending on your content needs.

How does a carousel compare to other navigation patterns like pagination or infinite scroll?

Carousels work well for highlighting a few key pieces of content but are not ideal for browsing large datasets. If users need to navigate through many items, consider using Pagination for structured navigation or Infinite Scroll for continuous content discovery.

Resources

Articles

Documentation

Last updated on