Refactoring UI with Tailwind + shadcn/ui
Apply professional design principles using Tailwind's design system and shadcn/ui components.
Core Principles
- •Start with functionality, not chrome - Design the feature first, not the shell
- •Work in grayscale first - Add color only after hierarchy is established
- •Use existing systems - Tailwind scale + shadcn components, don't reinvent
- •Hierarchy is everything - Not all elements deserve equal emphasis
Topic References
- •shadcn.md - Component patterns, composition, customization
- •hierarchy.md - Visual hierarchy, emphasis, contrast
- •spacing.md - Layout, whitespace, sizing
- •typography.md - Type scales, fonts, line-height
- •color.md - Palettes, shades, accessibility
- •depth.md - Shadows, elevation, layering
- •polish.md - Finishing touches, borders, backgrounds
Quick Start with shadcn/ui
Installation (Next.js)
bash
npx shadcn@latest init npx shadcn@latest add button card input label
Core Components to Know
| Component | Use for |
|---|---|
Button | Actions with built-in variants (default, secondary, outline, ghost, destructive) |
Card | Content containers with header, content, footer |
Input + Label | Form fields with consistent styling |
Dialog | Modals with accessible focus management |
DropdownMenu | Actions menus with keyboard navigation |
Select | Styled native-like selects |
Tabs | Content organization |
Badge | Status indicators, counts |
Alert | Feedback messages |
Skeleton | Loading states |
Button Hierarchy (shadcn)
tsx
// Primary: one per section max <Button>Save Changes</Button> // Secondary: clear but not dominant <Button variant="secondary">Cancel</Button> // Outline: lighter touch <Button variant="outline">Edit</Button> // Ghost: minimal, for toolbars/nav <Button variant="ghost">Settings</Button> // Destructive: dangerous actions (use sparingly) <Button variant="destructive">Delete</Button> // Link: text-only navigation <Button variant="link">Learn more</Button>
Common Patterns
Card with Hierarchy
tsx
<Card>
<CardHeader>
<CardTitle>Account Settings</CardTitle>
<CardDescription>Manage your account preferences.</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
{/* Form fields */}
</CardContent>
<CardFooter className="flex justify-end gap-2">
<Button variant="outline">Cancel</Button>
<Button>Save</Button>
</CardFooter>
</Card>
Form with Labels
tsx
<div className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input id="password" type="password" />
</div>
</div>
Alert Messages
tsx
<Alert> <InfoIcon className="h-4 w-4" /> <AlertTitle>Note</AlertTitle> <AlertDescription>Your session will expire in 5 minutes.</AlertDescription> </Alert> <Alert variant="destructive"> <AlertCircle className="h-4 w-4" /> <AlertTitle>Error</AlertTitle> <AlertDescription>Failed to save changes.</AlertDescription> </Alert>
Anti-Patterns
- •❌ Multiple primary buttons in one view
- •❌
variant="destructive"for non-destructive actions - •❌ Skipping
Labelcomponents (accessibility) - •❌ Overriding shadcn styles instead of using variants
- •❌ Not using
space-y-*orgap-*for consistent spacing - •❌ Arbitrary Tailwind values like
w-[423px](use scale) - •❌ Grey text on colored backgrounds (use same-hue shades)