Files
Felipe Cardoso 96df7edf88 Refactor useAuth hook, settings components, and docs for formatting and readability improvements
- 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.
2025-11-10 11:03:45 +01:00

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

  1. Grid vs Flex Decision Tree
  2. The 5 Essential Patterns
  3. Responsive Strategies
  4. Common Mistakes
  5. 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-width
  • mx-auto - Center horizontally
  • px-4 - Horizontal padding (mobile-friendly)
  • py-8 - Vertical padding
  • max-w-4xl - Constrain content width for readability
  • space-y-6 - Vertical spacing between children

When to use:

  • Blog posts
  • Documentation pages
  • Settings pages
  • Any page with readable content

See live example


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 Grid
  • grid-cols-1 - Default: 1 column (mobile-first)
  • md:grid-cols-2 - 2 columns on tablet
  • lg:grid-cols-3 - 3 columns on desktop
  • gap-6 - Consistent spacing between items

When to use:

  • Dashboards
  • Product grids
  • Image galleries
  • Card collections

See live example


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 form
  • space-y-4 - Vertical spacing between fields
  • w-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

See live example


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 layout
  • w-64 - Fixed sidebar width (256px)
  • flex-1 - Main content takes remaining space
  • min-h-screen - Full viewport height
  • border-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

See live example


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 content
  • prose - 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

See live example


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>

See before/after examples


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 gap or space-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


Related Documentation:

Last Updated: November 2, 2025