What do you need to know about carousel in 2025?


At first, I thought building a carousel would be simple. It’s just sliding some content with controls. What could possibly go wrong? But as I started digging deeper, more and more questions popped up:

Do I need navigation buttons for each slide?

How should I handle looping/infinite carousel?

How to handle accessibility?

In this blog, I’ll share my insights of designing a carousel, the challenges I faced, and the decisions I made along the way.

What controls I need?

Let’s start by examining the carousel navigation on www.nba.com on mobile. Do you notice anything that could be improved for a better user experience?

carousel for www.nba.com

There are two main issues:

  • ❌ Users can’t swipe between slides; the only option is to click on tiny line indicators acting as buttons, which is far from comfortable.
  • ❌ Why would a user click on one of those line buttons? They have no clue what content is behind each slide, so the interaction feels confusing and unintuitive.

Now let’s look on positive inspiration how google implement carousel:

carousel by google

So, what works well here?

  • ✅ There are indicator lines showing which slide you’re currently on, but they aren’t clickable. They serve purely as visual feedback.
  • ✅ Navigation is intuitive: on desktop, you have left and right buttons to move between slides. On mobile, you can either swipe or tap on the left or right side of the slide to go to the previous or next item.

Before you start, it’s important to understand what type of content your carousel will display. I recommend watching this video, which covers several key aspects of carousel design from a UX perspective.

You should decide whether you need navigation buttons for each slide, as this choice also affects the HTML structure from a semantic perspective. When navigation buttons are used for navigation, each slide functions similarly to a tab, which means they should have the accessible role of tabpanel.

Our carousel

In our codebase, we previously used an older carousel that relied on navigation dots to jump to specific slides. As mentioned earlier, this approach wasn’t ideal because there was no indication of what content lay beyond the current slide. To improve usability, we switched to left/right navigation buttons and added an information label to indicate the current slide. Additionally, we introduced a play/pause button to control autoplay, along with an animation that visually informs users when the next slide will appear.

Here’s what our carousel navigation looks like after the refactor:

our carousel controls

Current state of carousel in HTML world

Starting with Chrome 135, creating a carousel has become incredibly straightforward. With just a few lines of HTML and CSS, you can build a fully functional carousel without relying on JavaScript or external libraries. Let’s take a closer look at how it works:

<section class="carousel">
<div class="carousel-slide">
<h2>Slide 1</h2>
</div>
<div class="carousel-slide">
<h2>Slide 2</h2>
</div>
<div class="carousel-slide">
<h2>Slide 3</h2>
</div>
</section>
.carousel {
width: 400px;
height: 250px;
display: flex;

overflow-x: scroll;
scroll-snap-type: x mandatory;
}

.carousel-slide {
background-color: lightgray;
flex: 0 0 100%;

scroll-snap-align: center;
}

key to making this work lies in using scroll-snap-type on the entire carousel container and applying scroll-snap-align to each individual item within it.

You can find more details on adding buttons and other enhancements here:

Carousels with CSS | Blog | Chrome for Developers

For a simple carousel, JavaScript isn’t necessary. But if you’re looking to add features like autoplay or start/stop controls, or holding state of current slide you’ll probably need to include some JavaScript.

Carousel Limitations with Scroll Snap

One of the main limitations of implementing a carousel using scroll snap is creating a cyclical carousel. I mean allowing users to move seamlessly from the last slide straight back to the first. With scroll snap, this can be problematic because the user has to scroll through the entire content area to return to the beginning.

As mentioned in the article I linked earlier, the authors are exploring platform-level solutions to address this issue. On this GitHub page, they propose a simple overflow-based approach. For now, their recommended workaround is to either:

  • Move the content dynamically to the start or end of the carousel to enable continuous scrolling
  • Override the behaviour of the “next” button when the last item is reached, so it scrolls back to the beginning.

so how we implement cyclical carousel?

We duplicate the first slide and place it at the end of the carousel. This allows for a seamless looping effect. When the user reaches this duplicate slide, we instantly reset the index to 0. Since the duplicated slide looks identical to the first, the transition feels smooth and unnoticeable to the user.

Accessibility

To ensure accessibility in the carousel, I referred to several articles. The first one provides a more general overview.

Carousels Tutorial

The second article is more specific, focusing on scenarios where the carousel includes previous/next buttons or navigation indicators for each slide.

Carousel (Slide Show or Image Rotator) Pattern

From a screen reader perspective, the recommended experience is as follows: first, the user should encounter the carousel section as a whole; next, they should be able to navigate to the carousel controls; and finally, only the currently active slide should be announced.

Here are the steps:

1. Carousel section

We need a container element to hold the carousel, and <section> is a semantic choice that helps group related content. Adding aria-roledescription="carousel" makes it clear to assistive technologies that this is an interactive carousel widget.

<section id=”carousel-1” class=”carousel” aria-roledescription=”carousel” aria-label=”soccer players presentation”>

2. Individual slide

We need an element to represent each individual slide, and <div class="carousel-item active"> serves that purpose while marking the first slide as visible. The role="group" and aria-roledescription="slide" help screen reader users understand it's part of a carousel, and aria-label="1 of 6" tells them which slide they're on.

 <div class="carousel-item active"
role="group"
aria-roledescription="slide"
aria-label="1 of 6">

3. Controls

Based on accessibility tutorials, it’s recommended that screen readers first navigate to the carousel controls and then move to the currently active slide.

So this is how our controls look like:

carousel controls with autoplay

It’s a standard button for navigating to the next or previous slide, each with an appropriate ARIA label. There’s also an autoplay button that starts or stops the carousel’s automatic rotation, and when autoplay is active, it updates the aria-live attribute.

4. Aria live

The container element that holds all the slides should include the aria-live attribute to notify screen readers of changes when slides update. If autoplay is enabled, it's recommended to disable aria-live to avoid overwhelming users with frequent announcements.

<div aria-live={autoplay ? undefined : 'polite'}>

5. Others inactive slides not visible for screen reader

Since we’re scrolling between slides without hiding inactive ones using display: none, screen readers may announce all slides, even those not currently active. To prevent this, apply the inert attribute to inactive slides so they’re ignored by assistive technologies.

Bottom line

Nowadays, creating a carousel with the current HTML and CSS capabilities is much more straightforward and requires significantly less code than in the past. For simple carousels, you can often achieve the desired functionality using only HTML and CSS, especially in modern browsers.

The key consideration is ensuring a good user experience (UX). Think carefully about which controls are truly necessary for your carousel. It also influences your html markup.

The main challenge usually lies in implementing infinite scrolling. If you don’t need infinite scrolling, that simplifies things considerably. If you do, then you’ll need to choose one of the workarounds mentioned earlier.


What do you need to know about carousel in 2025? was originally published in ableneo tech & transformation on Medium, where people are continuing the conversation by highlighting and responding to this story.

Related