UI Styling Mastery
Build beautiful, accessible interfaces with shadcn/ui components and Tailwind CSS v4.
Core Stack
| Layer | Tool | Role |
|---|---|---|
| Components | shadcn/ui (Radix primitives) | Accessible, composable UI components |
| Styling | Tailwind CSS v4 | Utility-first CSS, zero runtime overhead |
| Theming | CSS Variables + next-themes | Dark mode, custom palettes |
| Icons | Lucide React | Consistent icon system |
Quick Start
bash
# Initialize shadcn/ui + Tailwind
npx shadcn@latest init
# Add components
npx shadcn@latest add button card dialog form input table
# Use in code
import { Button } from "@/components/ui/button"
<Button variant="default" size="lg">Click me</Button>
Reference Navigation
- •Component Catalog — All shadcn/ui components with usage patterns
- •Theming & Dark Mode — CSS variables, color palettes, next-themes, custom themes
- •Tailwind Utilities — Layout, spacing, typography, colors, responsive
- •Tailwind v4 Features — @theme directive, CSS-first config, container queries
- •Accessibility Patterns — ARIA, keyboard nav, focus management, screen readers
- •Responsive Design — Mobile-first, breakpoints, adaptive layouts
Key Patterns
Form with Validation
tsx
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
const schema = z.object({
email: z.string().email(),
password: z.string().min(8)
})
export function LoginForm() {
const form = useForm({ resolver: zodResolver(schema) })
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(console.log)} className="space-y-6">
<FormField control={form.control} name="email" render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl><Input type="email" {...field} /></FormControl>
<FormMessage />
</FormItem>
)} />
<Button type="submit" className="w-full">Sign In</Button>
</form>
</Form>
)
}
Responsive Layout with Dark Mode
tsx
<div className="min-h-screen bg-background text-foreground">
<div className="container mx-auto px-4 py-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<Card>
<CardContent className="p-6">
<h3 className="text-xl font-semibold">Content</h3>
</CardContent>
</Card>
</div>
</div>
</div>
Best Practices
- •Utility-First: Use Tailwind classes directly, extract components only for true repetition
- •Mobile-First: Start with mobile styles, layer
md:,lg:variants - •Accessibility-First: Use Radix primitives, add focus-visible states
- •CSS Variables: Use
--variablefor consistent theming - •Dark Mode: Apply
dark:variants, use semantic color names (bg-background) - •Performance: Automatic CSS purging, avoid dynamic class names
Related Skills
| Skill | When to Use |
|---|---|
| frontend-design | Design tokens, typography, spacing systems |
| nextjs-turborepo | Next.js styling integration |
| ui-polish | Visual refinement, polish checklist |