Layout Patterns
Common layout patterns for building responsive, well-structured pages. These patterns solve 80% of layout challenges you'll encounter.
Page Container
Center content with max-width and horizontal padding:
// Basic container
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* Page content */}
</div>
// Narrower for content pages
<div className="max-w-3xl mx-auto px-4">
{/* Article content */}
</div>
// Full width with padding
<div className="w-full px-4 sm:px-6 lg:px-8">
{/* Dashboard content */}
</div>Sidebar Layout
Fixed sidebar with scrollable main content (like this docs site):
<div className="flex min-h-screen">
{/* Sidebar - fixed width, sticky */}
<aside className="sticky top-0 h-screen w-64 shrink-0 overflow-y-auto border-r">
<nav className="p-4">
{/* Navigation links */}
</nav>
</aside>
{/* Main content - flexible width */}
<main className="flex-1 min-w-0 p-8">
{/* Page content */}
</main>
</div>Key points:
shrink-0- Prevents sidebar from shrinkingmin-w-0- Allows main content to shrink below content sizesticky top-0- Keeps sidebar visible while scrollingh-screen overflow-y-auto- Independent sidebar scrolling
Sticky Header Layout
<div className="min-h-screen flex flex-col">
{/* Header - sticky at top */}
<header className="sticky top-0 z-50 h-16 border-b bg-white/80 backdrop-blur">
<nav className="h-full max-w-7xl mx-auto px-4 flex items-center">
{/* Logo, nav links */}
</nav>
</header>
{/* Main content - grows to fill space */}
<main className="flex-1">
{/* Page content */}
</main>
{/* Footer - at bottom */}
<footer className="border-t py-8">
{/* Footer content */}
</footer>
</div>Card Grid
Responsive grid that adapts to screen size:
// Auto-fit grid (cards stretch to fill)
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
<Card>...</Card>
<Card>...</Card>
<Card>...</Card>
</div>
// Fixed columns with auto-placement
<div className="grid grid-cols-[repeat(auto-fill,minmax(300px,1fr))] gap-6">
{/* Cards automatically wrap */}
</div>
// Masonry-like with CSS columns (for varying heights)
<div className="columns-1 sm:columns-2 lg:columns-3 gap-6 space-y-6">
<Card>...</Card>
<Card>...</Card>
</div>Split Layout (50/50)
Two-column layout that stacks on mobile:
// Hero with image
<section className="grid lg:grid-cols-2 gap-8 items-center">
<div className="space-y-4">
<h1 className="text-4xl font-bold">Headline</h1>
<p className="text-lg text-gray-600">Description text</p>
<Button>Get Started</Button>
</div>
<div className="aspect-video bg-gray-100 rounded-lg">
<img src="/hero.jpg" alt="" className="w-full h-full object-cover" />
</div>
</section>
// Form beside info (reverse on mobile)
<div className="flex flex-col-reverse lg:flex-row gap-8">
<div className="flex-1">
{/* Form */}
</div>
<div className="flex-1 lg:max-w-md">
{/* Info sidebar */}
</div>
</div>Centered Content
// Centered hero section
<section className="min-h-[60vh] flex items-center justify-center text-center px-4">
<div className="max-w-2xl">
<h1 className="text-5xl font-bold">Big Headline</h1>
<p className="mt-4 text-xl text-gray-600">Supporting text</p>
<div className="mt-8 flex justify-center gap-4">
<Button>Primary</Button>
<Button variant="outline">Secondary</Button>
</div>
</div>
</section>
// Login/signup form centered
<div className="min-h-screen flex items-center justify-center p-4">
<Card className="w-full max-w-md">
{/* Form content */}
</Card>
</div>List with Actions
// List item with content and actions
<ul className="divide-y">
{items.map(item => (
<li key={item.id} className="flex items-center justify-between py-4">
<div className="flex items-center gap-4 min-w-0">
<Avatar>{item.avatar}</Avatar>
<div className="min-w-0">
<p className="font-medium truncate">{item.name}</p>
<p className="text-sm text-gray-500 truncate">{item.email}</p>
</div>
</div>
<div className="flex items-center gap-2 ml-4">
<Button size="sm" variant="ghost">Edit</Button>
<Button size="sm" variant="ghost">Delete</Button>
</div>
</li>
))}
</ul>Note: min-w-0 and truncate prevent long text from breaking layout.
Dashboard Layout
<div className="min-h-screen bg-gray-50">
{/* Top navbar */}
<header className="sticky top-0 z-40 h-16 bg-white border-b">
{/* ... */}
</header>
<div className="flex">
{/* Sidebar navigation */}
<aside className="sticky top-16 h-[calc(100vh-4rem)] w-64 border-r bg-white">
<nav className="p-4 space-y-1">
{/* Nav items */}
</nav>
</aside>
{/* Main content area */}
<main className="flex-1 p-6">
{/* Stats row */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<Card>Stat 1</Card>
<Card>Stat 2</Card>
<Card>Stat 3</Card>
<Card>Stat 4</Card>
</div>
{/* Two column layout */}
<div className="grid lg:grid-cols-3 gap-6">
<Card className="lg:col-span-2">Main chart</Card>
<Card>Recent activity</Card>
</div>
</main>
</div>
</div>Responsive Tips
Mobile First
Start with mobile layout, add complexity at larger breakpoints.grid-cols-1 md:grid-cols-2 lg:grid-cols-3
Hide/Show
Hide elements at certain breakpoints.hidden md:block or md:hidden
Stack → Row
Stack vertically on mobile, horizontal on desktop.flex flex-col md:flex-row
Adjust Spacing
Use smaller spacing on mobile.p-4 md:p-6 lg:p-8