1 Tailwind5 with JSPublished 2026-10-05Free · no sign-up
Six carousels in Tailwind: a scroll-snap carousel with arrows, a sliding track with dots, an auto-rotating fade with a pause button, slides that peek in from the side, a two-up product row and a row with a progress bar.
A swipeable carousel built on native scrolling with snap-x snap-mandatory, plus previous and next buttons that scroll by one slide. Each slide is labelled with its position, such as 2 of 4.
var t = document.getElementById('twcr1');
document.querySelectorAll('[data-dir]').forEach(function (b) { b.onclick = function () { t.scrollBy({ left: b.dataset.dir * t.clientWidth, behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth' }); }; });
02. Tailwind Carousel with Dot Navigation
TailwindCarouselDots
Tips slide along a track moved with translate, and dot buttons jump between them; the current dot has aria-current. Slides that are out of view are made inert and hidden from assistive technology.
View code
<section aria-roledescription="carousel" aria-label="Store tips" class="w-full max-w-xs">
<div class="overflow-hidden rounded-2xl">
<ul id="twcr2" class="flex transition-transform duration-500 motion-reduce:transition-none">
<li role="group" aria-roledescription="slide" aria-label="1 of 3" class="w-full shrink-0 bg-slate-800 p-5 text-slate-100"><p class="text-xs font-bold uppercase tracking-wider text-sky-300">Tip 1</p><p class="mt-1 text-sm">Keep product titles under 60 characters so they fit in search results.</p></li>
<li role="group" aria-roledescription="slide" aria-label="2 of 3" class="w-full shrink-0 bg-slate-800 p-5 text-slate-100"><p class="text-xs font-bold uppercase tracking-wider text-sky-300">Tip 2</p><p class="mt-1 text-sm">Put the returns policy one click from every product page.</p></li>
<li role="group" aria-roledescription="slide" aria-label="3 of 3" class="w-full shrink-0 bg-slate-800 p-5 text-slate-100"><p class="text-xs font-bold uppercase tracking-wider text-sky-300">Tip 3</p><p class="mt-1 text-sm">Test checkout on a phone before every launch.</p></li>
</ul>
</div>
<div id="twcr2d" class="mt-3 flex justify-center gap-2"><button type="button" aria-label="Show slide 1" class="size-2.5 rounded-full bg-slate-600 aria-[current=true]:w-6 aria-[current=true]:bg-sky-400 transition-all focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300"></button><button type="button" aria-label="Show slide 2" class="size-2.5 rounded-full bg-slate-600 aria-[current=true]:w-6 aria-[current=true]:bg-sky-400 transition-all focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300"></button><button type="button" aria-label="Show slide 3" class="size-2.5 rounded-full bg-slate-600 aria-[current=true]:w-6 aria-[current=true]:bg-sky-400 transition-all focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300"></button></div>
</section>
var track = document.getElementById('twcr2'), dots = document.querySelectorAll('#twcr2d button'), slides = track.children;
function go(i) { track.style.transform = 'translateX(-' + i * 100 + '%)'; [].forEach.call(slides, function (s, k) { s.inert = k !== i; s.setAttribute('aria-hidden', k !== i); }); dots.forEach(function (d, k) { if (k === i) d.setAttribute('aria-current', 'true'); else d.removeAttribute('aria-current'); }); }
dots.forEach(function (d, k) { d.onclick = function () { go(k); }; });
go(0);
03. Tailwind Auto-Rotating Fade Carousel
TailwindCarouselAutoplay
Slides cross-fade every four seconds, with a Pause button that must be there for anything that moves on its own. Autoplay never starts for people who prefer reduced motion, and the slide region becomes polite live only while paused.
var box = document.getElementById('twcr3'), s = box.children, p = document.getElementById('twcr3p'), i = 0, t = null;
function show(n) { [].forEach.call(s, function (el, k) { el.style.opacity = k === n ? 1 : 0; el.setAttribute('aria-hidden', k !== n); }); }
function play() { t = setInterval(function () { i = (i + 1) % s.length; show(i); }, 4000); p.textContent = 'Pause'; box.setAttribute('aria-live', 'off'); }
function pause() { clearInterval(t); t = null; p.textContent = 'Play'; box.setAttribute('aria-live', 'polite'); }
p.onclick = function () { if (t) pause(); else play(); };
show(0); if (matchMedia('(prefers-reduced-motion: reduce)').matches) pause(); else play();
04. Tailwind Peeking Card Carousel
TailwindCarouselPeek
Each slide is 80% of the width so the next one peeks in from the side, a clear hint that the row can be swiped. snap-center centres each slide and scroll-px keeps the first and last from touching the edge.
Two product cards visible at once with arrow buttons that disable themselves at either end. The script reads the scroll position after every scroll, so swiping and the buttons always agree.
var t = document.getElementById('twcr5'), a = document.getElementById('twcr5a'), b = document.getElementById('twcr5b');
function upd() { a.disabled = t.scrollLeft <= 2; b.disabled = t.scrollLeft >= t.scrollWidth - t.clientWidth - 2; }
a.onclick = function () { t.scrollBy({ left: -t.clientWidth, behavior: 'smooth' }); };
b.onclick = function () { t.scrollBy({ left: t.clientWidth, behavior: 'smooth' }); };
t.addEventListener('scroll', upd); upd();
06. Tailwind Carousel with Scroll Progress Bar
TailwindCarouselProgress
A swipeable row of slides with a thin bar underneath that fills as you scroll through them. The bar width is scrollLeft divided by the scrollable distance, updated on every scroll event, and it is decorative only.
var t = document.getElementById('twcr6'), bar = document.getElementById('twcr6b');
function upd() { var max = t.scrollWidth - t.clientWidth; bar.style.width = (max ? t.scrollLeft / max * 100 : 100) + '%'; }
t.addEventListener('scroll', upd); upd();
About these Tailwind Image Carousels
Native scrolling first
flex snap-x snap-mandatory overflow-x-auto gives swipe, trackpad and keyboard scrolling for free; buttons only add scrollBy.
Label slides and the carousel
Use aria-roledescription="carousel" with a label, and label each slide with its position such as 2 of 4.
Anything that moves needs pause
Autoplay must have a visible pause control, and should not start at all for people who prefer reduced motion.
Out-of-view slides
When slides are moved with transforms, make hidden ones inert so focus never lands off-screen.
Frequently asked questions
Which demos need JavaScript?
The arrows, dots, autoplay and progress bar; the peeking row is CSS only.
Are carousels good for conversions?
Important content should not hide in later slides; show key items without needing to swipe.