Skip to content

Carousel

A carousel displays a sequence of slides in a scrollable track. It is commonly used for featured content, hero sections, and media galleries.

<div class="tng-carousel">
<div class="tng-carousel-track">
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 1</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 2</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 3</div>
</div>
</div>
</div>

Carousel controls render a list of item buttons used to navigate between slides. The active item displays a top progress bar that fills over time.

Use position utilities to overlay them on the carousel: add p-relative to .tng-carousel and p-absolute at-bottom inset-lg to .tng-carousel-controls.

<div class="tng-carousel p-relative">
<div class="tng-carousel-track">
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 1</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 2</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 3</div>
</div>
</div>
<div class="tng-carousel-controls p-absolute at-bottom inset-lg">
<button class="tng-carousel-control">Item 1</button>
<button class="tng-carousel-control is-active" disabled>
Item 2
</button>
<button class="tng-carousel-control">Item 3</button>
</div>
</div>

The active progress animation duration is controlled by the custom property --tng-carousel-control-progress-duration.

  • Apply it on .tng-carousel-controls to set one duration for all items. The default is 5 seconds.
  • Apply it on .tng-carousel-control to set duration per asset.
<div
class="tng-carousel-controls"
style="--tng-carousel-control-progress-duration: 5s;"
>
<button class="tng-carousel-control">Asset 1</button>
<button
class="tng-carousel-control"
style="--tng-carousel-control-progress-duration: 8s;"
>
Asset 2
</button>
<button class="tng-carousel-control">Asset 3</button>
</div>
  • The progress fill runs only on .tng-carousel-control.is-active.
  • The bar uses rested color for remaining track and active color for completed progress.
  • Hover changes indicator thickness and hover track color for non-disabled items.
  • Under reduced motion, active items render at full progress without animation.

The count indicator can be overlaid on the carousel using the same position utilities: p-relative on .tng-carousel and p-absolute at-bottom inset-lg on .tng-count-indicator.

<div class="tng-carousel p-relative">
<div class="tng-carousel-track">
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 1</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 2</div>
</div>
<div class="tng-carousel-slide">
<div class="tng-slot" style="block-size: 300px">Slide 3</div>
</div>
</div>
<div
class="tng-count-indicator p-absolute at-bottom inset-lg"
style="width: 200px"
>
<div class="tng-count-indicator-helper">1 of 3</div>
<div class="tng-count-indicator-dots">
<div class="is-current"></div>
<div></div>
<div></div>
</div>
<div class="tng-count-indicator-buttons">
<button class="tng-icon-button is-sm" aria-label="Previous">
<i class="tng-icon icon-chevron-left" aria-hidden="true"></i>
</button>
<button class="tng-icon-button is-sm" aria-label="Next">
<i class="tng-icon icon-chevron-right" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
source code