Tailwind CSS
Tailwind configuration and utilities
Tailwind CSS provides utility-first styling with a customized configuration for this project.
Configuration
Tailwind is configured in tailwind.config.ts:
import type { Config } from "tailwindcss";
const config: Config = {
darkMode: ["class"],
content: [
"./src/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
// Semantic color tokens
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
// ... more colors
},
// Custom spacing, fonts, etc.
},
},
};Design Tokens
Colors
Always use semantic color tokens instead of specific colors:
// ✅ Good - semantic tokens
<div className="bg-primary text-primary-foreground" />
<p className="text-muted-foreground" />
// ❌ Bad - specific colors
<div className="bg-blue-500 text-white" />
<p className="text-gray-600" />Color Tokens
| Token | Purpose | CSS Variable |
|---|---|---|
background | Page background | --background |
foreground | Primary text | --foreground |
primary | Primary actions | --primary |
primary-foreground | Text on primary | --primary-foreground |
secondary | Secondary actions | --secondary |
muted | Muted backgrounds | --muted |
muted-foreground | Muted text | --muted-foreground |
accent | Accent highlights | --accent |
destructive | Destructive actions | --destructive |
border | Border colors | --border |
ring | Focus rings | --ring |
Spacing
Use the default Tailwind spacing scale:
<div className="p-4"> {/* 16px padding */}
<div className="m-8"> {/* 32px margin */}
<div className="gap-2"> {/* 8px gap */}
<div className="space-y-6"> {/* 24px vertical spacing */}| Class | Size |
|---|---|
*-0 | 0px |
*-1 | 4px |
*-2 | 8px |
*-3 | 12px |
*-4 | 16px |
*-6 | 24px |
*-8 | 32px |
*-12 | 48px |
*-16 | 64px |
cn() Helper
Use the cn() utility for combining classes:
import { cn } from "@/lib/utils";
<div className={cn(
"base-class",
isActive && "active-class",
variant === "primary" && "primary-class"
)} />This function:
- Combines multiple class strings
- Handles conditional classes
- Resolves Tailwind conflicts using
tailwind-merge
Example
// Without cn()
<div className={`p-4 ${isActive ? "bg-primary" : "bg-secondary"} ${className}`} />
// With cn()
<div className={cn(
"p-4",
isActive ? "bg-primary" : "bg-secondary",
className
)} />Customization
Extending Colors
Add custom colors in tailwind.config.ts:
theme: {
extend: {
colors: {
brand: {
50: "#f0f9ff",
100: "#e0f2fe",
// ... more shades
},
},
},
},Then use: bg-brand-500, text-brand-600, etc.
Custom Utilities
Add custom utilities using @layer:
/* src/styles/globals.css */
@layer utilities {
.text-balance {
text-wrap: balance;
}
.scrollbar-hide {
scrollbar-width: none;
-ms-overflow-style: none;
}
}Common Patterns
Container
<div className="container mx-auto px-4">
{/* Centered container with padding */}
</div>Card
<div className="rounded-lg border bg-card p-6 shadow-sm">
{/* Card with border, background, padding, shadow */}
</div>Flex Layout
<div className="flex items-center justify-between gap-4">
{/* Horizontal flex with center alignment and gap */}
</div>Grid Layout
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Responsive grid */}
</div>Responsive Design
Use breakpoint prefixes:
<div className="w-full md:w-1/2 lg:w-1/3">
{/* Responsive widths */}
</div>| Prefix | Breakpoint |
|---|---|
sm: | 640px |
md: | 768px |
lg: | 1024px |
xl: | 1280px |
2xl: | 1536px |
Dark Mode
Use the dark: prefix for dark mode styles:
<div className="bg-white dark:bg-gray-900">
{/* White in light mode, dark gray in dark mode */}
</div>Dark mode uses the class strategy, controlled by the theme provider.
Arbitrary Values
Avoid Arbitrary Values
Do not use arbitrary values like w-[100px] or text-[#ff0000]. Use design tokens and semantic classes for consistency.
// ❌ Bad - arbitrary values
<div className="w-[123px] text-[#ff0000]" />
// ✅ Good - design tokens
<div className="w-32 text-destructive" />Best Practices
- Use semantic colors - Always use color tokens like
primary, never specific colors - Follow spacing scale - Use the standard spacing scale for consistency
- Use cn() helper - For combining and conditional classes
- Avoid arbitrary values - Stick to design tokens and theme values
- Mobile-first - Write base styles for mobile, add responsive variants