Skip to main content Skip to docs navigation

Create fluid, touch-enabled content sliders with Chassis CSS's carousel component, featuring smooth transitions and comprehensive accessibility support.

Introduction

Carousels in Chassis CSS deliver smooth, touch-enabled content sliders designed for modern web experiences. Built with CSS 3D transforms and intelligent JavaScript controls, carousels seamlessly integrate with your design system while maintaining optimal performance and accessibility standards.

Chassis CSS carousels operate on a performance-first architecture, using explicit JavaScript initialization to prevent unnecessary overhead while ensuring optimal loading performance. The positioning system leverages CSS 3D transforms to deliver hardware-accelerated transitions with smooth visual effects across all supported browsers.

Touch support is built into the core experience, providing native swipe gestures alongside keyboard navigation and traditional mouse controls. The autoplay system intelligently manages pause and resume behavior based on user interaction and page visibility, while comprehensive ARIA support ensures compatibility with screen readers and assistive technologies.

Chassis CSS carousels use explicit initialization to prevent performance overhead on unused components. Initialize carousels using the constructor method before user interaction. Carousels with data-cx-ride="carousel" initialize automatically on page load, so avoid duplicate initialization when using this attribute.

Note that nested carousels are not supported—consider accessibility implications and provide alternative navigation methods for complex content.

Chassis CSS respects user accessibility preferences by automatically disabling animations when the prefers-reduced-motion media query is detected. See the reduced motion guidelines in our accessibility documentation for implementation details.

Examples

Explore practical carousel implementations showcasing Chassis CSS's flexible architecture and comprehensive feature set. These examples demonstrate real-world usage patterns from basic content sliders to advanced interactive experiences.

Basic structure

This foundational example demonstrates the essential carousel structure with navigation controls. Chassis CSS recommends semantic <button> elements for optimal accessibility, though <a> elements with role="button" are supported for specific design requirements.

html
<div id="carouselExample" class="carousel slide">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExample" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExample" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Enhance user experience with direct slide navigation through indicator controls. Indicators provide immediate access to specific slides and visual feedback about current position within the content sequence.

html
<div id="carouselExampleIndicators" class="carousel slide">
  <div class="carousel-indicators">
    <button type="button" data-cx-target="#carouselExampleIndicators" data-cx-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
    <button type="button" data-cx-target="#carouselExampleIndicators" data-cx-slide-to="1" aria-label="Slide 2"></button>
    <button type="button" data-cx-target="#carouselExampleIndicators" data-cx-slide-to="2" aria-label="Slide 3"></button>
  </div>
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleIndicators" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleIndicators" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Content captions

Add contextual information to slides with the .carousel-caption element. Chassis CSS captions integrate seamlessly with the utility system for responsive behavior. Use display utilities to control caption visibility across viewport sizes—this example uses .d-none for mobile and .medium:d-block for larger screens.

html
<div id="carouselExampleCaptions" class="carousel slide">
  <div class="carousel-indicators">
    <button type="button" data-cx-target="#carouselExampleCaptions" data-cx-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button>
    <button type="button" data-cx-target="#carouselExampleCaptions" data-cx-slide-to="1" aria-label="Slide 2"></button>
    <button type="button" data-cx-target="#carouselExampleCaptions" data-cx-slide-to="2" aria-label="Slide 3"></button>
  </div>
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
      <div class="carousel-caption d-none medium:d-block">
        <h5>First slide label</h5>
        <p>Some representative placeholder content for the first slide.</p>
      </div>
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
      <div class="carousel-caption d-none medium:d-block">
        <h5>Second slide label</h5>
        <p>Some representative placeholder content for the second slide.</p>
      </div>
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
      <div class="carousel-caption d-none medium:d-block">
        <h5>Third slide label</h5>
        <p>Some representative placeholder content for the third slide.</p>
      </div>
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleCaptions" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleCaptions" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Fade transitions

Transform slide behavior with elegant fade transitions using .carousel-fade. This alternative animation style works particularly well with text-heavy content or when seeking subtle visual transitions. For optimal crossfading with certain content types, consider adding .bg-main or custom backgrounds to .carousel-item elements.

html
<div id="carouselExampleFade" class="carousel slide carousel-fade">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleFade" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleFade" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Autoplay behavior

Chassis CSS carousels support intelligent autoplay functionality with comprehensive user interaction controls. Set the ride option to carousel for immediate autoplay on page load. The system automatically pauses on mouse hover and respects the Page Visibility API to stop cycling when pages aren't visible.

Chassis CSS recommends providing explicit pause/stop controls for autoplaying carousels to ensure compliance with WCAG 2.2 Success Criterion 2.2.2 Pause, Stop, Hide and improve user experience for all users.

html
<div id="carouselExampleAutoplaying" class="carousel slide" data-cx-ride="carousel">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleAutoplaying" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleAutoplaying" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Setting ride to true (rather than carousel) enables user-triggered autoplay—the carousel begins cycling only after the first user interaction, providing a balance between automation and user control.

html
<div id="carouselExampleRide" class="carousel slide" data-cx-ride="true">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleRide" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleRide" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Timing control

Fine-tune autoplay timing with data-cx-interval attributes on individual .carousel-item elements. This feature enables dynamic pacing—for example, allowing more time for text-heavy slides while maintaining quicker transitions for simple images.

html
<div id="carouselExampleInterval" class="carousel slide" data-cx-ride="carousel">
  <div class="carousel-inner">
    <div class="carousel-item active" data-cx-interval="10000">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item" data-cx-interval="2000">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleInterval" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleInterval" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

Minimal implementation

Create distraction-free content displays with slides-only carousels. This pattern works particularly well for hero sections, testimonials, or background imagery where controls might interfere with the design aesthetic. Remember to include .d-block and .w-100 classes for optimal image presentation.

html
<div id="carouselExampleSlidesOnly" class="carousel slide" data-cx-ride="carousel">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
</div>

Touch interaction control

Chassis CSS carousels include native touch/swipe support for mobile and tablet experiences. When touch interactions conflict with your interface design or content requirements, disable swiping by setting the touch option to false while maintaining traditional control functionality.

html
<div id="carouselExampleControlsNoTouching" class="carousel slide" data-cx-touch="false">
  <div class="carousel-inner">
    <div class="carousel-item active">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <button class="carousel-control-prev" type="button" data-cx-target="#carouselExampleControlsNoTouching" data-cx-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Previous</span>
  </button>
  <button class="carousel-control-next" type="button" data-cx-target="#carouselExampleControlsNoTouching" data-cx-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="visually-hidden">Next</span>
  </button>
</div>

CSS

This component is customized exclusively through Sass variables during compilation rather than exposed CSS custom properties.

Sass variables

These Sass variables control the component's appearance and can be modified in the project's variables file before compilation.

$carousel-control-color:              $fg-inverse;
$carousel-control-size:               15%;
$carousel-control-opacity:            .5;
$carousel-control-hover-opacity:      .9;
$carousel-control-transition:         opacity .15s ease;
// hit zone = size + padding * 2
$carousel-indicator-width:            2rem; //determines hit zone
$carousel-indicator-height:           .5rem; //determines hit zone
$carousel-indicator-padding-y:        .5rem; //determines hit zone
$carousel-indicator-padding-x:        .25rem; //determines hit zone
$carousel-indicator-border-radius:    .5rem;
$carousel-indicator-margin:           0;
$carousel-indicator-opacity:          .5;
$carousel-indicator-color:            $fg-inverse;
$carousel-indicator-active-opacity:   1;
$carousel-indicator-transition:       opacity .6s ease;

$carousel-caption-width:              70%;
$carousel-caption-color:              $white;
$carousel-caption-padding-y:          1.25rem;
$carousel-caption-spacer:             1.25rem;

$carousel-control-icon-size:          2rem;

$carousel-control-prev-icon:          url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='currentColor'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/></svg>");
$carousel-control-next-icon:          url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='currentColor'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/></svg>");

$carousel-transition-duration:        .6s;
$carousel-transition:                 transform $carousel-transition-duration ease-in-out; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)

JavaScript API

Control carousel behavior programmatically with Chassis CSS's comprehensive JavaScript interface, featuring smooth transitions, autoplay management, and accessibility controls.

Data attributes

Configure carousel behavior declaratively through data attributes for simple implementation without JavaScript initialization.

Use data-cx-slide with prev or next keywords for relative navigation, or data-cx-slide-to with numeric values for direct slide access (zero-indexed, like arrays).

Initialization

Initialize carousels programmatically for advanced control and configuration:

const carousel = new chassis.Carousel('#myCarousel')

Options

Chassis components offer flexible configuration through both data attributes and JavaScript. To use data attributes, prefix any option with data-cx- followed by the option name in kebab-case format (using hyphens instead of camelCase). For example, write data-cx-custom-class="my-class" rather than data-cx-customClass="my-class".

For more complex configurations, Chassis provides the data-cx-config attribute which accepts a JSON string of multiple settings. This approach simplifies markup when configuring several options at once. If the same option appears in both data-cx-config and as a separate data attribute (like data-cx-title), the individual attribute takes precedence. You can also use JSON values in individual attributes, such as data-cx-delay='{"show":100,"hide":200}' for more granular control.

When initializing components, Chassis merges configurations from multiple sources in this priority order: default settings, data-cx-config values, individual data-cx-* attributes, and finally any JavaScript object options. Values defined later in this sequence override earlier ones.

NameTypeDefaultDescription
intervalnumber5000Autoplay timing in milliseconds between slide transitions.
keyboardbooleantrueEnable keyboard navigation (arrow keys) for carousel control.
pausestring, boolean"hover"Pause behavior: "hover" pauses on mouse interaction, false disables pausing. Touch devices pause on touchend for two intervals after user interaction.
ridestring, booleanfalseAutoplay mode: true starts after first interaction, "carousel" starts immediately on load.
touchbooleantrueEnable touch/swipe gestures for slide navigation on mobile devices.
wrapbooleantrueContinuous cycling (true) or hard stops at first/last slides (false).

Methods

All Chassis CSS component methods are asynchronous and initiate CSS transitions. Methods return immediately when the transition begins, not when it completes. Calling methods on components that are already transitioning will be ignored to prevent conflicts. Learn more about Chassis JavaScript patterns.

Create carousel instances with comprehensive configuration options. For example, to initialize an autoplay carousel with custom timing and disabled touch support:

const myCarouselElement = document.querySelector('#myCarousel')

const carousel = new chassis.Carousel(myCarouselElement, {
  interval: 2000,
  touch: false
})
MethodDescription
cycleInitiates automatic cycling through carousel items from left to right.
disposeCompletely destroys the carousel instance and removes all stored DOM data.
getInstanceStatic method returning the carousel instance associated with a DOM element: chassis.Carousel.getInstance(element).
getOrCreateInstanceStatic method that returns existing carousel instance or creates new one if uninitialized: chassis.Carousel.getOrCreateInstance(element).
nextAdvances to next slide. Returns immediately before transition completes (before slid.cx.carousel event).
nextWhenVisibleSmart next navigation that respects page/element visibility. Returns before target slide is shown.
pauseHalts automatic cycling while preserving current state.
prevMoves to previous slide. Returns immediately before transition completes (before slid.cx.carousel event).
toDirect navigation to specific slide by index (zero-based). Returns before target slide is shown.

Events

Chassis CSS carousels provide comprehensive event hooks for application integration and analytics.

  • direction: Transition direction ("left" or "right")
  • relatedTarget: DOM element becoming the active slide
  • from: Current slide index
  • to: Target slide index

All events fire at the carousel element (<div class="carousel">) and include detailed transition information:

Event typeDescription
slid.cx.carouselFired when slide transition animation completes.
slide.cx.carouselFired immediately when slide transition begins.
const myCarousel = document.getElementById('myCarousel')

myCarousel.addEventListener('slide.cx.carousel', event => {
  // Access event properties for analytics or custom logic
  console.log(`Sliding from ${event.from} to ${event.to}`)
})