Files
fast-next-template/frontend/docs/design-system/03-layouts.md
Felipe Cardoso 30cbaf8ad5 Add documentation for component creation and design system structure
- **Component Creation Guide:** Document best practices for creating reusable, accessible components using CVA patterns. Includes guidance on when to compose vs create, decision trees, templates, prop design, testing checklists, and real-world examples.
- **Design System README:** Introduce an organized structure for the design system documentation with quick navigation, learning paths, and reference links to key topics. Includes paths for quick starts, layouts, components, forms, and AI setup.
2025-11-02 12:32:01 +01:00

13 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