Crash Courses · Masters
Component Patterns
Build reusable, composable UI components using Tailwind utility patterns.
11 min read+175 XP on completionCert: Tailwind CSS Crash Course
Tap any word in the text below to start reading from there.
Component Patterns
In Tailwind, components live in your component files â€" not CSS. Extract via React components with variant props.
Button Component with Variants
import { cn } from '@/lib/utils'
import { cva, type VariantProps } from 'class-variance-authority'
const buttonVariants = cva(
// base
"inline-flex items-center justify-center rounded-lg font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none",
{
variants: {
variant: {
primary: "bg-amber-500 text-white hover:bg-amber-600 focus:ring-amber-500",
secondary: "bg-gray-100 text-gray-900 hover:bg-gray-200 focus:ring-gray-500",
ghost: "hover:bg-gray-100 text-gray-700",
destructive: "bg-red-600 text-white hover:bg-red-700 focus:ring-red-500",
},
size: {
sm: "h-8 px-3 text-sm",
md: "h-10 px-4 text-sm",
lg: "h-12 px-6 text-base",
},
},
defaultVariants: { variant: "primary", size: "md" },
}
)
interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
export function Button({ className, variant, size, ...props }: ButtonProps) {
return (
<button className={cn(buttonVariants({ variant, size }), className)} {...props} />
)
}
// Usage
<Button variant="primary" size="lg">Start Course</Button>
<Button variant="ghost">Cancel</Button>Course Card Component
function CourseCard({ course }: { course: Course }) {
return (
<div className="
group bg-white dark:bg-gray-800
border border-gray-200 dark:border-gray-700
rounded-2xl overflow-hidden
hover:shadow-lg hover:-translate-y-0.5
transition-all duration-200
">
<div className="p-5">
<div className="flex items-center justify-between mb-3">
<Badge level={course.level} />
<span className="text-xs text-gray-500">{course.duration} min</span>
</div>
<h3 className="font-semibold text-gray-900 dark:text-white mb-2">
{course.title}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400 line-clamp-2">
{course.subtitle}
</p>
</div>
<div className="px-5 pb-4 flex items-center justify-between">
<span className="text-xs font-medium text-amber-600">{course.xp} XP</span>
<span className="text-xs text-gray-400">Module {course.module}</span>
</div>
</div>
)
}Reading progress
0% read
In this module
Component extraction
Variant props
cva()
shadcn/ui
0%