- Consolidated multi-line arguments into single lines where appropriate in `useAuth`. - Improved spacing and readability in data processing across components (`ProfileSettingsForm`, `PasswordChangeForm`, `SessionCard`). - Applied consistent table and markdown formatting in design system docs (e.g., `README.md`, `08-ai-guidelines.md`, `00-quick-start.md`). - Updated code snippets to ensure adherence to Prettier rules and streamlined JSX structures.
14 KiB
Layout Patterns
Master the 5 essential layouts that cover 80% of all interface needs. Learn when to use Grid vs Flex, and build responsive, consistent layouts every time.
Table of Contents
- Grid vs Flex Decision Tree
- The 5 Essential Patterns
- Responsive Strategies
- Common Mistakes
- Advanced Patterns
Grid vs Flex Decision Tree
Use this flowchart to choose between Grid and Flex:
┌─────────────────────────────────────┐
│ Need equal-width columns? │
│ (e.g., 3 cards of same width) │
└──────────┬─YES──────────┬─NO────────┘
│ │
▼ ▼
USE GRID Need 2D layout?
(rows + columns)
│
┌────┴────┐
│YES │NO
▼ ▼
USE GRID USE FLEX
Quick Rules
| Scenario | Solution |
|---|---|
| Equal-width columns | Grid (grid grid-cols-3) |
| Flexible item sizes | Flex (flex gap-4) |
| 2D layout (rows + cols) | Grid (grid grid-cols-2 grid-rows-3) |
| 1D layout (row OR col) | Flex (flex or flex flex-col) |
| Card grid | Grid (grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3) |
| Navbar items | Flex (flex items-center gap-4) |
| Sidebar + Content | Flex (flex gap-6) |
| Form fields | Flex column (flex flex-col gap-4 or space-y-4) |
The 5 Essential Patterns
These 5 patterns cover 80% of all layout needs. Master these first.
1. Page Container Pattern
Use case: Standard page layout with readable content width
<div className="container mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto space-y-6">
<h1 className="text-3xl font-bold">Page Title</h1>
<Card>
<CardHeader>
<CardTitle>Section Title</CardTitle>
</CardHeader>
<CardContent>Page content goes here</CardContent>
</Card>
</div>
</div>
Key Features:
container- Responsive container with max-widthmx-auto- Center horizontallypx-4- Horizontal padding (mobile-friendly)py-8- Vertical paddingmax-w-4xl- Constrain content width for readabilityspace-y-6- Vertical spacing between children
When to use:
- Blog posts
- Documentation pages
- Settings pages
- Any page with readable content
2. Dashboard Grid Pattern
Use case: Responsive card grid that adapts to screen size
<div className="container mx-auto px-4 py-8">
<h1 className="text-3xl font-bold mb-6">Dashboard</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{items.map((item) => (
<Card key={item.id}>
<CardHeader>
<CardTitle>{item.title}</CardTitle>
<CardDescription>{item.description}</CardDescription>
</CardHeader>
<CardContent>
<p className="text-2xl font-bold">{item.value}</p>
</CardContent>
</Card>
))}
</div>
</div>
Responsive behavior:
- Mobile (
< 768px): 1 column - Tablet (
≥ 768px): 2 columns - Desktop (
≥ 1024px): 3 columns
Key Features:
grid- Use CSS Gridgrid-cols-1- Default: 1 column (mobile-first)md:grid-cols-2- 2 columns on tabletlg:grid-cols-3- 3 columns on desktopgap-6- Consistent spacing between items
When to use:
- Dashboards
- Product grids
- Image galleries
- Card collections
3. Form Layout Pattern
Use case: Centered form with constrained width
<div className="container mx-auto px-4 py-8">
<Card className="max-w-md mx-auto">
<CardHeader>
<CardTitle>Login</CardTitle>
<CardDescription>Enter your credentials to continue</CardDescription>
</CardHeader>
<CardContent>
<form 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>
<Button className="w-full">Sign In</Button>
</form>
</CardContent>
</Card>
</div>
Key Features:
max-w-md- Constrain form width (448px max)mx-auto- Center the formspace-y-4- Vertical spacing between fieldsw-full- Full-width button
Form width guidelines:
- Short forms (login, signup):
max-w-md(448px) - Medium forms (profile, settings):
max-w-lg(512px) - Long forms (checkout):
max-w-2xl(672px)
When to use:
- Login/signup forms
- Contact forms
- Settings forms
- Any single-column form
4. Sidebar Layout Pattern
Use case: Sidebar navigation with main content area
<div className="flex min-h-screen">
{/* Sidebar */}
<aside className="w-64 border-r bg-muted/40 p-6">
<nav className="space-y-2">
<a href="#" className="block rounded-lg px-3 py-2 text-sm hover:bg-accent">
Dashboard
</a>
<a href="#" className="block rounded-lg px-3 py-2 text-sm hover:bg-accent">
Settings
</a>
</nav>
</aside>
{/* Main Content */}
<main className="flex-1 p-6">
<div className="max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-6">Page Title</h1>
{/* Content */}
</div>
</main>
</div>
Key Features:
flex- Horizontal layoutw-64- Fixed sidebar width (256px)flex-1- Main content takes remaining spacemin-h-screen- Full viewport heightborder-r- Visual separator
Responsive strategy:
// Mobile: Collapsible sidebar
<div className="flex min-h-screen">
{/* Sidebar - hidden on mobile */}
<aside className="hidden lg:block w-64 border-r p-6">
{/* Sidebar content */}
</aside>
{/* Main content - full width on mobile */}
<main className="flex-1 p-4 lg:p-6">
{/* Content */}
</main>
</div>
// Add mobile menu button
<Button size="icon" className="lg:hidden">
<Menu className="h-6 w-6" />
</Button>
When to use:
- Admin dashboards
- Settings pages
- Documentation sites
- Apps with persistent navigation
5. Centered Content Pattern
Use case: Single-column content with optimal reading width
<div className="container mx-auto px-4 py-8">
<article className="max-w-2xl mx-auto">
<h1 className="text-4xl font-bold mb-4">Article Title</h1>
<p className="text-muted-foreground mb-8">Published on Nov 2, 2025</p>
<div className="prose prose-lg">
<p>Article content with optimal line length for reading...</p>
<p>More content...</p>
</div>
</article>
</div>
Key Features:
max-w-2xl- Optimal reading width (672px)mx-auto- Center contentprose- Typography styles (if using @tailwindcss/typography)
Width recommendations:
- Articles/Blogs:
max-w-2xl(672px) - Documentation:
max-w-3xl(768px) - Landing pages:
max-w-4xl(896px) or wider - Forms:
max-w-md(448px)
When to use:
- Blog posts
- Articles
- Documentation
- Long-form content
Responsive Strategies
Mobile-First Approach
Always start with mobile layout, then enhance for larger screens:
// ✅ CORRECT - Mobile first
<div className="
p-4 // Mobile: 16px padding
sm:p-6 // Tablet: 24px padding
lg:p-8 // Desktop: 32px padding
">
<div className="
grid
grid-cols-1 // Mobile: 1 column
sm:grid-cols-2 // Tablet: 2 columns
lg:grid-cols-3 // Desktop: 3 columns
gap-4
">
{/* Items */}
</div>
</div>
// ❌ WRONG - Desktop first
<div className="p-8 md:p-6 sm:p-4"> // Don't do this
Breakpoints
| Breakpoint | Min Width | Typical Use |
|---|---|---|
sm: |
640px | Large phones, small tablets |
md: |
768px | Tablets |
lg: |
1024px | Laptops, desktops |
xl: |
1280px | Large desktops |
2xl: |
1536px | Extra large screens |
Responsive Grid Columns
// 1→2→3→4 progression (common)
grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4
// 1→2→3 progression (most common)
grid-cols-1 md:grid-cols-2 lg:grid-cols-3
// 1→2 progression (simple)
grid-cols-1 md:grid-cols-2
// 1→3 progression (skip 2)
grid-cols-1 lg:grid-cols-3
Responsive Text
// Heading sizes
<h1 className="
text-2xl sm:text-3xl lg:text-4xl
font-bold
">
Responsive Title
</h1>
// Body text (usually doesn't need responsive sizes)
<p className="text-base">
Body text stays consistent
</p>
Common Mistakes
❌ Mistake 1: Using Margins Instead of Gap
// ❌ WRONG - Children have margins
<div className="flex">
<div className="mr-4">Item 1</div>
<div className="mr-4">Item 2</div>
<div>Item 3</div> {/* Last one has no margin */}
</div>
// ✅ CORRECT - Parent controls spacing
<div className="flex gap-4">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
❌ Mistake 2: Fixed Widths Instead of Responsive
// ❌ WRONG - Fixed width, not responsive
<div className="w-[800px]">
Content
</div>
// ✅ CORRECT - Responsive width
<div className="w-full max-w-4xl mx-auto px-4">
Content
</div>
❌ Mistake 3: Not Using Container
// ❌ WRONG - Content touches edges on large screens
<div className="px-4">
Content spans full width on 4K screens
</div>
// ✅ CORRECT - Container constrains width
<div className="container mx-auto px-4">
Content has maximum width
</div>
❌ Mistake 4: Desktop-First Responsive
// ❌ WRONG - Desktop first
<div className="p-8 lg:p-6 md:p-4">
// ✅ CORRECT - Mobile first
<div className="p-4 md:p-6 lg:p-8">
❌ Mistake 5: Using Flex for Equal Columns
// ❌ WRONG - Flex doesn't guarantee equal widths
<div className="flex gap-4">
<div className="flex-1">Col 1</div>
<div className="flex-1">Col 2</div>
<div className="flex-1">Col 3</div>
</div>
// ✅ CORRECT - Grid ensures equal widths
<div className="grid grid-cols-3 gap-4">
<div>Col 1</div>
<div>Col 2</div>
<div>Col 3</div>
</div>
Advanced Patterns
Asymmetric Grid
// 2/3 - 1/3 split
<div className="grid grid-cols-3 gap-6">
<div className="col-span-2">Main content (2/3 width)</div>
<div className="col-span-1">Sidebar (1/3 width)</div>
</div>
Auto-fit Grid (Flexible columns)
// Columns adjust based on available space
<div className="grid grid-cols-[repeat(auto-fit,minmax(300px,1fr))] gap-6">
<Card>Item 1</Card>
<Card>Item 2</Card>
<Card>Item 3</Card>
{/* Adds as many columns as fit */}
</div>
Sticky Sidebar
<div className="flex gap-6">
<aside className="sticky top-6 h-fit w-64">{/* Stays in view while scrolling */}</aside>
<main className="flex-1">{/* Scrollable content */}</main>
</div>
Full-height Layout
<div className="flex flex-col min-h-screen">
<header className="h-16 border-b">Header</header>
<main className="flex-1">Flexible content</main>
<footer className="h-16 border-t">Footer</footer>
</div>
Layout Checklist
Before implementing a layout, ask:
- Responsive? Does it work on mobile, tablet, desktop?
- Container? Is content constrained on large screens?
- Spacing? Using
gaporspace-y, not margins on children? - Mobile-first? Starting with mobile layout?
- Semantic? Using appropriate HTML tags (main, aside, nav)?
- Accessible? Proper heading hierarchy, skip links?
Quick Reference
Grid Cheat Sheet
// Basic grid
grid grid-cols-3 gap-6
// Responsive grid
grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6
// Asymmetric grid
grid grid-cols-3 gap-6
<div className="col-span-2">...</div>
// Auto-fit grid
grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-6
Flex Cheat Sheet
// Horizontal flex
flex gap-4
// Vertical flex
flex flex-col gap-4
// Center items
flex items-center justify-center
// Space between
flex items-center justify-between
// Wrap items
flex flex-wrap gap-4
Container Cheat Sheet
// Standard container
container mx-auto px-4 py-8
// Constrained width
max-w-4xl mx-auto px-4
// Full width
w-full px-4
Next Steps
- Practice: Build pages using the 5 essential patterns
- Explore: Interactive layout examples
- Deep Dive: Spacing Philosophy
- Reference: Quick Reference Tables
Related Documentation:
- Spacing Philosophy - When to use margin vs padding vs gap
- Foundations - Spacing tokens and scale
- Quick Start - Essential patterns
Last Updated: November 2, 2025