EmpireUI
Sign inGet Pro
← BlogEnglish · 6 minreact carouseltailwind sliderreact components

How to Build a React Carousel (Free Tailwind Slider)

Learn how to build a fully functional react carousel with Tailwind CSS — from basic slide transitions to auto-play, indicators, and beautiful styled variants.

What Is a React Carousel and Why Build One?

A react carousel is a UI component that cycles through a collection of slides — images, cards, testimonials, or any content — within a fixed viewport. Carousels are ubiquitous on landing pages, product galleries, and portfolios because they pack rich content into minimal vertical space without overwhelming the user.

Building your own carousel from scratch gives you full design control with zero dependency bloat. Libraries that ship a pre-styled carousel often force you to override dozens of CSS rules or accept a visual style you didn't choose. With React state and Tailwind utility classes you can have a production-ready slider in under 60 lines of code.

Empire UI takes this further by providing styled component templates that plug straight into your project. But understanding the fundamentals first makes you a far better consumer of any component library. This guide walks you from zero to a polished, accessible carousel step by step.

Setting Up the Project

Assuming you already have a Next.js or Vite React project with Tailwind CSS installed, you only need React's built-in useState and useEffect hooks — no extra packages required. If you are starting fresh, run npx create-next-app@latest my-carousel --tailwind and you are ready in seconds.

Create a new file at components/Carousel.tsx (or .jsx if you prefer JavaScript). The component will accept a slides prop — an array of objects each containing at minimum an image URL and an alt string. Keeping the data separate from the component makes it reusable across every page of your app.

For this tutorial we will also add optional autoPlay and interval props so the carousel can advance on its own. This is the most common product request when building sliders for marketing pages and hero sections. You can explore more interactive motion patterns on Empire UI's animated backgrounds page for inspiration on complementary effects.

Building the Core Carousel Component

Below is a complete, accessible react carousel built with React hooks and Tailwind CSS. It supports keyboard navigation, auto-play with pause-on-hover, previous/next controls, and dot indicators. ``tsx import { useState, useEffect, useCallback } from 'react'; interface Slide { image: string; alt: string; caption?: string; } interface CarouselProps { slides: Slide[]; autoPlay?: boolean; interval?: number; } export default function Carousel({ slides, autoPlay = true, interval = 4000, }: CarouselProps) { const [current, setCurrent] = useState(0); const [paused, setPaused] = useState(false); const prev = useCallback(() => setCurrent((c) => (c === 0 ? slides.length - 1 : c - 1)), [slides.length]); const next = useCallback(() => setCurrent((c) => (c === slides.length - 1 ? 0 : c + 1)), [slides.length]); useEffect(() => { if (!autoPlay || paused) return; const timer = setInterval(next, interval); return () => clearInterval(timer); }, [autoPlay, paused, interval, next]); return ( <div className="relative w-full overflow-hidden rounded-2xl" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)} > {/* Slides */} <div className="flex transition-transform duration-500 ease-in-out" style={{ transform: translateX(-${current * 100}%) }} > {slides.map((slide, i) => ( <div key={i} className="min-w-full relative"> <img src={slide.image} alt={slide.alt} className="w-full h-72 object-cover" /> {slide.caption && ( <p className="absolute bottom-4 left-4 text-white font-semibold bg-black/40 px-3 py-1 rounded-lg text-sm"> {slide.caption} </p> )} </div> ))} </div> {/* Prev / Next */} <button onClick={prev} aria-label="Previous slide" className="absolute left-3 top-1/2 -translate-y-1/2 bg-white/70 hover:bg-white rounded-full p-2 shadow transition" > &#8592; </button> <button onClick={next} aria-label="Next slide" className="absolute right-3 top-1/2 -translate-y-1/2 bg-white/70 hover:bg-white rounded-full p-2 shadow transition" > &#8594; </button> {/* Dot indicators */} <div className="absolute bottom-3 left-1/2 -translate-x-1/2 flex gap-2"> {slides.map((_, i) => ( <button key={i} onClick={() => setCurrent(i)} aria-label={Go to slide ${i + 1}} className={w-2.5 h-2.5 rounded-full transition ${ i === current ? 'bg-white scale-125' : 'bg-white/50' }} /> ))} </div> </div> ); } ``

The key technique here is a single flex container whose translateX is driven by current * 100%. Each slide is min-w-full, so they line up horizontally and the overflow is clipped by the parent's overflow-hidden. This avoids absolute positioning every slide, keeping the DOM clean and the CSS minimal.

The paused state toggled on hover prevents the auto-play timer from advancing while the user is interacting — a critical UX detail that is easy to overlook. The useCallback wrappers on prev and next stabilise the references so the useEffect dependency array does not cause unnecessary re-subscriptions.

Styling Variants — Glassmorphism, Neobrutalism, and More

Plain white controls look fine, but your brand deserves more. Empire UI offers 40 visual styles you can apply directly to your carousel. Here are two quick variants using Tailwind alone.

Glassmorphism carousel — replace the slide container class with bg-white/10 backdrop-blur-md border border-white/20 and swap the nav buttons to bg-white/20 backdrop-blur-sm. A subtle frosted-glass overlay on the caption makes text readable over any image. See the full glassmorphism palette on the glassmorphism page.

Neobrutalism carousel — add border-4 border-black shadow-[6px_6px_0_#000] to the outer wrapper and style the nav buttons as solid black squares with white text. The intentionally heavy borders and offset box shadows are the hallmark of the neobrutalism aesthetic. Browse ready-made components on the templates page to mix and match styles without writing everything from scratch.

You can also pair your carousel with one of Empire UI's custom cursor styles to reinforce the interactive feel — a spotlight or trailing cursor makes sliding through images feel premium and intentional.

Accessibility and Performance Best Practices

Every carousel must be usable by keyboard and screen-reader users. Wrap the component in <section aria-label="Image carousel" aria-roledescription="carousel"> and add aria-roledescription="slide" plus aria-label={\Slide ${i + 1} of ${slides.length}\} to each slide div. This satisfies WCAG 2.1 success criterion 4.1.2.

For performance, lazy-load off-screen slides with the native loading="lazy" attribute on <img> tags. If you are using Next.js, swap <img> for <Image> from next/image to get automatic format optimisation (AVIF/WebP) and size hints. This can reduce carousel image payload by 40–70% with zero code changes.

Consider adding prefers-reduced-motion support: wrap the CSS transition in a motion-safe: Tailwind variant or check window.matchMedia('(prefers-reduced-motion: reduce)') before enabling auto-play. Users with vestibular disorders rely on this setting, and respecting it takes fewer than five lines of code.

Finally, test your carousel on mobile. Touch/swipe support is the most requested feature after auto-play. You can add it with a touchstart / touchend handler that computes deltaX and calls prev() or next() — or use the MCP server to generate a full swipe-enabled variant automatically from a plain-text prompt.

Using Empire UI's Pre-Built Carousel Components

If you would rather ship faster than build from scratch, Empire UI's component library includes production-ready carousel variants styled across multiple design systems — glassmorphism, neumorphism, claymorphism, and neobrutalism out of the box. Visit the templates page to preview industry-specific layouts where carousels are wired into full page designs.

The [MCP server](/mcp) is the fastest path: describe your carousel in a sentence — "a glassmorphism product image carousel with auto-play and dot indicators" — and the MCP tool generates the full component code, props interface, and Tailwind classes. It works inside Cursor, VS Code with Copilot Chat, or any editor that supports the Model Context Protocol.

All Empire UI components are MIT-licensed and free forever. There are no paywalled variants, no watermarks, and no usage limits. Explore the full blog for tutorials on complementary components like animated tabs, marquee sliders, and bento grids that pair naturally with a carousel on landing pages.

FAQ

What is the best way to build a react carousel without a library?

Use React's useState to track the active index and a flex container with overflow-hidden driven by translateX. This approach requires zero dependencies, works with any CSS framework, and gives you full control over transitions and styling.

How do I add swipe support to a React carousel on mobile?

Listen for touchstart and touchend events on the slide container, calculate the horizontal delta, and call your prev() or next() function when the delta exceeds a threshold (typically 50px). Alternatively, use the Empire UI MCP server to generate a fully swipe-enabled component from a text prompt.

How do I make a Tailwind CSS carousel auto-advance?

Store a paused boolean in state and toggle it on mouseenter/mouseleave. Inside a useEffect, call setInterval(next, interval) only when autoPlay is true and paused is false, and always clear the interval in the cleanup function to prevent memory leaks.

Is a react carousel bad for SEO?

Carousels can hurt SEO if content is hidden behind JavaScript and not crawlable. Render all slides in the DOM (not conditionally) and use display: none / aria-hidden only for visual hiding. Next.js server-side rendering ensures slide content is in the initial HTML, making it fully indexable.

Can I use Empire UI carousel components for free?

Yes — all Empire UI components are MIT-licensed and completely free, including carousel variants styled in glassmorphism, neobrutalism, claymorphism, and more. There are no tiers, paywalls, or attribution requirements beyond the open-source license.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

Free Marquee Component for React — Infinite Scroll Logos & TextHow to Build Animated Tabs in React + Tailwind (Free)What Is a Bento Grid? Free React + Tailwind Layout GuideFree Stacked Cards Component for React — Cards Stack Animation