# Spacing Philosophy **Master the "parent controls children" spacing strategy** that eliminates 90% of layout inconsistencies. Learn when to use margin, padding, or gap—and why children should never add their own margins. --- ## Table of Contents 1. [The Golden Rules](#the-golden-rules) 2. [Parent Controls Children Strategy](#parent-controls-children-strategy) 3. [Decision Tree: Margin vs Padding vs Gap](#decision-tree-margin-vs-padding-vs-gap) 4. [Common Patterns](#common-patterns) 5. [Before/After Examples](#beforeafter-examples) 6. [Anti-Patterns to Avoid](#anti-patterns-to-avoid) 7. [Quick Reference](#quick-reference) --- ## The Golden Rules These 5 rules eliminate 90% of spacing inconsistencies: ### Rule 1: Parent Controls Children **Children don't add their own margins. The parent controls spacing between siblings.** ```tsx // ✅ CORRECT - Parent controls spacing
Item 1 Item 2 Item 3
// ❌ WRONG - Children add margins
Item 1 Item 2 Item 3 {/* Inconsistent: last one has no margin */}
``` **Why this matters:** - Eliminates "last child" edge cases - Makes components reusable (they work in any context) - Changes propagate from one place (parent) - Prevents margin collapsing bugs --- ### Rule 2: Use Gap for Siblings **For flex and grid layouts, use `gap-*` to space siblings.** ```tsx // ✅ CORRECT - Gap for flex/grid
1 2 3
// ❌ WRONG - Children with margins
``` --- ### Rule 3: Use Padding for Internal Spacing **Padding is for spacing _inside_ a component, between the border and content.** ```tsx // ✅ CORRECT - Padding for internal spacing Title Content // ❌ WRONG - Using margin for internal spacing Title ``` --- ### Rule 4: Use space-y for Vertical Stacks **For vertical stacks (not flex/grid), use `space-y-*` utility.** ```tsx // ✅ CORRECT - space-y for stacks
``` **Spacing breakdown:** - `space-y-4` on form: 16px between field groups - `space-y-2` on field group: 8px between label and input - No margins on children --- ### Pattern 2: Button Group (Horizontal Flex) ```tsx // ✅ CORRECT
// Responsive: stack on mobile, row on desktop
``` **Why gap over space-x:** - Works with `flex-wrap` - Works with `flex-col` (changes direction) - Consistent spacing in all directions --- ### Pattern 3: Card Grid ```tsx // ✅ CORRECT
Item 1 Item 2 Item 3
``` **Why gap:** - Consistent spacing between rows and columns - Works with responsive grid changes - No edge cases (first row, last column, etc.) --- ### Pattern 4: Card Internal Spacing ```tsx // ✅ CORRECT Title Description

Paragraph 1

Paragraph 2

``` **Spacing breakdown:** - `p-6` on Card: 24px internal padding - `space-y-4` on CardContent: 16px between paragraphs - `pt-4` on CardFooter: Additional top padding for visual separation --- ### Pattern 5: Page Layout ```tsx // ✅ CORRECT

Page Title

Section 1 Content Section 2 Content
``` **Spacing breakdown:** - `px-4`: Horizontal padding (prevents edge touching) - `py-8`: Vertical padding (top and bottom spacing) - `space-y-6`: 24px between sections - No margins on children --- ## Before/After Examples ### Example 1: Button Group #### ❌ Before (Child-Controlled) ```tsx function ActionButton({ children, className }: Props) { return ; } // Usage
Cancel Save Delete {/* Unwanted mr-4 */}
; ``` **Problems:** - Last button has unwanted margin - Can't change spacing without modifying component - Hard to use in vertical layout #### ✅ After (Parent-Controlled) ```tsx function ActionButton({ children, className }: Props) { return ; } // Usage
Cancel Save Delete
// Different context: vertical
Cancel Save
``` **Benefits:** - No edge cases - Reusable in any layout - Easy to change spacing --- ### Example 2: List Items #### ❌ Before (Child-Controlled) ```tsx function ListItem({ title, description }: Props) { return (

{title}

{description}

); }
{/* Unwanted mb-6 */}
; ``` **Problems:** - Last item has unwanted bottom margin - Can't change list spacing without modifying component - Internal `mb-2` hard to override #### ✅ After (Parent-Controlled) ```tsx function ListItem({ title, description }: Props) { return (

{title}

{description}

); }
// Different context: compact spacing
``` **Benefits:** - No unwanted margins - Internal spacing controlled by `space-y-2` - Reusable with different spacings --- ### Example 3: Form Fields #### ❌ Before (Mixed Strategy) ```tsx
``` **Problems:** - Spacing scattered across children - Hard to change consistently - Have to remember `mt-6` for button #### ✅ After (Parent-Controlled) ```tsx
``` **Benefits:** - Spacing controlled in 2 places: form (`space-y-4`) and field groups (`space-y-2`) - Easy to change all field spacing at once - Consistent and predictable --- ## Anti-Patterns to Avoid ### Anti-Pattern 1: Last Child Special Case ```tsx // ❌ WRONG { items.map((item, index) => ( {item.name} )); } // ✅ CORRECT
{items.map((item) => ( {item.name} ))}
; ``` --- ### Anti-Pattern 2: Negative Margins to Fix Spacing ```tsx // ❌ WRONG - Using negative margin to fix unwanted spacing
{/* Canceling out previous margin */} Content
// ✅ CORRECT - Parent controls spacing
Content
``` **Why negative margins are bad:** - Indicates broken spacing strategy - Hard to maintain - Creates coupling between components --- ### Anti-Pattern 3: Mixing Gap and Child Margins ```tsx // ❌ WRONG - Gap + child margins = unpredictable spacing
{/* gap + mr-2 = 24px */}
// ✅ CORRECT - Only gap
// ✅ CORRECT - Exception case
{/* Intentional extra space */}
``` --- ### Anti-Pattern 4: Using Margins for Layout ```tsx // ❌ WRONG - Using margins to create layout
{/* Pushing content for sidebar */} Content
// ✅ CORRECT - Use proper layout (flex/grid)
Content
``` --- ## Quick Reference ### Spacing Method Cheat Sheet | Use Case | Method | Example | | ----------------------- | ----------- | ------------ | | **Flex siblings** | `gap-*` | `flex gap-4` | | **Grid siblings** | `gap-*` | `grid gap-6` | | **Vertical stack** | `space-y-*` | `space-y-4` | | **Horizontal stack** | `space-x-*` | `space-x-2` | | **Inside component** | `p-*` | `p-6` | | **One child exception** | `m-*` | `mt-8` | ### Common Spacing Values | Class | Pixels | Usage | | ---------------------- | ----------- | ---------------------- | | `gap-2` or `space-y-2` | 8px | Tight (label + input) | | `gap-4` or `space-y-4` | 16px | Standard (form fields) | | `gap-6` or `space-y-6` | 24px | Sections (cards) | | `gap-8` or `space-y-8` | 32px | Large gaps | | `p-4` | 16px | Standard padding | | `p-6` | 24px | Card padding | | `px-4 py-8` | 16px / 32px | Page padding | ### Decision Flowchart (Simplified) ``` Need spacing? │ ├─ Between siblings? │ ├─ Flex/Grid parent? → gap-* │ └─ Regular parent? → space-y-* or space-x-* │ ├─ Inside component? → p-* │ └─ Exception case? → m-* (sparingly) ``` --- ## Best Practices Summary ### Do ✅ 1. **Use parent-controlled spacing** (`gap`, `space-y`, `space-x`) 2. **Use `gap-*` for flex and grid** layouts 3. **Use `space-y-*` for vertical stacks** (forms, content) 4. **Use `p-*` for internal spacing** (padding inside components) 5. **Use margin only for exceptions** (mt-8 to separate sections) 6. **Let components be context-agnostic** (no built-in margins) ### Don't ❌ 1. ❌ Add margins to reusable components 2. ❌ Use last-child selectors or conditional margins 3. ❌ Mix gap with child margins 4. ❌ Use negative margins to fix spacing 5. ❌ Use margins for layout (use flex/grid) 6. ❌ Hard-code spacing in child components --- ## Spacing Checklist Before implementing spacing, verify: - [ ] **Parent controls children?** Using gap or space-y/x? - [ ] **No child margins?** Components don't have mb-_ or mr-_? - [ ] **Consistent method?** Not mixing gap + child margins? - [ ] **Reusable components?** Work in different contexts? - [ ] **No edge cases?** No last-child or first-child special handling? - [ ] **Semantic spacing?** Using design system scale (4, 8, 12, 16...)? --- ## Next Steps - **Practice**: Refactor existing components to use parent-controlled spacing - **Explore**: [Interactive spacing examples](/dev/spacing) - **Reference**: [Quick Reference Tables](./99-reference.md) - **Layout Patterns**: [Layouts Guide](./03-layouts.md) --- **Related Documentation:** - [Layouts](./03-layouts.md) - When to use Grid vs Flex - [Foundations](./01-foundations.md) - Spacing scale tokens - [Component Creation](./05-component-creation.md) - Building reusable components - [Quick Start](./00-quick-start.md) - Essential patterns **Last Updated**: November 2, 2025