Tailwind

How do you build a reusable button component with Tailwind that supports multiple variants?

March 18, 2026

download ready
Thank You
Your submission has been received.
We will be in touch and contact you soon!

Creating a reusable Tailwind CSS button component with multiple variants requires structuring the code step-by-step to handle base styles, variant styles, size styles, and props merging clearly.

Breaking down the component construction into concise steps improves readability and scalability. Each step focuses on a specific aspect, defining style maps, setting up prop types, merging classes dynamically, and rendering the button.

Step 1:-

Import React and clsx (for conditional class merging)

Code

import React from "react";
import clsx from "clsx";
      

Step 2:-

Define prop types, including variants and sizes

Code

type ButtonProps = {
  variant?: "primary" | "secondary" | "ghost"; // Variants of button
  size?: "sm" | "md" | "lg"; // Sizes of button
  className?: string; // Additional classes users may pass
  children: React.ReactNode; // Button content
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
      

Step 3:-

Map variants to Tailwind classes

Code

const variantClasses = {
  primary: "bg-blue-600 text-white hover:bg-blue-700",
  secondary: "bg-gray-300 text-gray-700 hover:bg-gray-400",
  ghost: "bg-transparent text-blue-600 hover:bg-blue-100",
};
      

Step 4:-

Map sizes to Tailwind classes

Code

const sizeClasses = {
  sm: "px-2 py-1 text-sm",
  md: "px-4 py-2 text-base",
  lg: "px-6 py-3 text-lg",
};
      

Step 5:-

Create Button component

Code

export default function Button({
  variant = "primary",
  size = "md",
  className,
  children,
  ...props
}: ButtonProps) {
  return (
    <button
      className={clsx(
        "rounded font-semibold focus:outline-none focus:ring-2 focus:ring-offset-2",
        variantClasses[variant],
        sizeClasses[size],
        className
      )}
      {...props}
    >
      {children}
    </button>
  );
}
      
Hire Now!

Need Help with Tailwind Development ?

Work with our skilled tailwind developers to accelerate your project and boost its performance.
**Hire now**Hire Now**Hire Now**Hire now**Hire now

How do you build a reusable button component with Tailwind that supports multiple variants?

Creating a reusable Tailwind CSS button component with multiple variants requires structuring the code step-by-step to handle base styles, variant styles, size styles, and props merging clearly.

Breaking down the component construction into concise steps improves readability and scalability. Each step focuses on a specific aspect, defining style maps, setting up prop types, merging classes dynamically, and rendering the button.

Step 1:-

Import React and clsx (for conditional class merging)

Code

import React from "react";
import clsx from "clsx";
      

Step 2:-

Define prop types, including variants and sizes

Code

type ButtonProps = {
  variant?: "primary" | "secondary" | "ghost"; // Variants of button
  size?: "sm" | "md" | "lg"; // Sizes of button
  className?: string; // Additional classes users may pass
  children: React.ReactNode; // Button content
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
      

Step 3:-

Map variants to Tailwind classes

Code

const variantClasses = {
  primary: "bg-blue-600 text-white hover:bg-blue-700",
  secondary: "bg-gray-300 text-gray-700 hover:bg-gray-400",
  ghost: "bg-transparent text-blue-600 hover:bg-blue-100",
};
      

Step 4:-

Map sizes to Tailwind classes

Code

const sizeClasses = {
  sm: "px-2 py-1 text-sm",
  md: "px-4 py-2 text-base",
  lg: "px-6 py-3 text-lg",
};
      

Step 5:-

Create Button component

Code

export default function Button({
  variant = "primary",
  size = "md",
  className,
  children,
  ...props
}: ButtonProps) {
  return (
    <button
      className={clsx(
        "rounded font-semibold focus:outline-none focus:ring-2 focus:ring-offset-2",
        variantClasses[variant],
        sizeClasses[size],
        className
      )}
      {...props}
    >
      {children}
    </button>
  );
}