DEV Community

Cover image for Building a Tab Component with Tailwind CSS and React
HexShift
HexShift

Posted on

Building a Tab Component with Tailwind CSS and React

Tabs are a common UI pattern for switching between different views or content areas. With React and Tailwind CSS, building a scalable and responsive tab component is clean and efficient.


Why Use Tabs?

  • Organize related content in a compact space
  • Enhance usability without extra navigation
  • Avoid unnecessary page reloads or routing

Component Structure

We'll build the following components:

  • Tabs – manages active state
  • TabList – container for tab buttons
  • Tab – a single clickable tab
  • TabPanels – container for tab content
  • TabPanel – content area for each tab

Tabs.js

import { useState, createContext, useContext } from 'react'

const TabsContext = createContext()

export function Tabs({ children, defaultIndex = 0 }) {
  const [activeIndex, setActiveIndex] = useState(defaultIndex)
  return (
    <TabsContext.Provider value={{ activeIndex, setActiveIndex }}>
      <div>{children}</div>
    </TabsContext.Provider>
  )
}

export function TabList({ children }) {
  return <div className="flex border-b">{children}</div>
}

export function Tab({ index, children }) {
  const { activeIndex, setActiveIndex } = useContext(TabsContext)
  const isActive = index === activeIndex
  return (
    <button
      onClick={() => setActiveIndex(index)}
      className={`px-4 py-2 -mb-px border-b-2 transition-colors ${
        isActive
          ? 'border-indigo-500 text-indigo-600 font-medium'
          : 'border-transparent text-gray-500 hover:text-gray-700'
      }`}
    >
      {children}
    </button>
  )
}

export function TabPanels({ children }) {
  const { activeIndex } = useContext(TabsContext)
  return <div className="p-4">{children[activeIndex]}</div>
}

export function TabPanel({ children }) {
  return <div>{children}</div>
}
Enter fullscreen mode Exit fullscreen mode

Example Usage

import {
  Tabs,
  TabList,
  Tab,
  TabPanels,
  TabPanel,
} from './Tabs'

function App() {
  return (
    <div className="max-w-xl mx-auto mt-10">
      <Tabs defaultIndex={0}>
        <TabList>
          <Tab index={0}>Overview</Tab>
          <Tab index={1}>Pricing</Tab>
          <Tab index={2}>Reviews</Tab>
        </TabList>
        <TabPanels>
          <TabPanel>
            <p>Welcome to the overview section.</p>
          </TabPanel>
          <TabPanel>
            <p>Check out our competitive pricing.</p>
          </TabPanel>
          <TabPanel>
            <p>Read customer reviews here.</p>
          </TabPanel>
        </TabPanels>
      </Tabs>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Tailwind Styling Tips

  • Use border-b and -mb-px for underline animation
  • Highlight active tab with font-medium and color utilities
  • Add transitions for smooth switching

Enhancements

  • Add keyboard support with ArrowLeft/ArrowRight
  • Animate tab panel content with framer-motion
  • Lazy-load tab content for performance
  • Sync tab state with URL for shareable views

Summary

Building tab components with Tailwind CSS and React Context keeps code modular, styled, and scalable. This approach separates concerns while offering great control over the look and behavior.


For a complete reference on scaling Tailwind in component libraries, check out:

Mastering Tailwind at Scale: Architecture, Patterns & Performance


Keep UI logic clean and tabs accessible with this pattern - and give users a seamless navigation experience.

Top comments (0)