The CSS Box Model
Every element in HTML is represented as a rectangular box. The CSS Box Model describes the geometry of that box — its four layers that together determine how much space the element takes up and where it sits on the page.
1. The Four Layers
┌─────────────────────────────────────────┐
│ MARGIN │ ← Transparent. Separates from other elements.
│ ┌─────────────────────────────────┐ │
│ │ BORDER │ │ ← Visual border (has color, style, width).
│ │ ┌─────────────────────────┐ │ │
│ │ │ PADDING │ │ │ ← Transparent. Space inside the border.
│ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ CONTENT │ │ │ │ ← Text, images, children.
│ │ │ │ (width/height) │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────┘ │ │ │
│ │ └─────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
- Content — Where text and child elements render. Sized by
widthandheight. - Padding — Transparent space between the content and the border. Inherits the element's background color.
- Border — A visible line around the padding and content. Has
width,style, andcolor. - Margin — Transparent space outside the border. Separates this element from neighboring elements.
2. The box-sizing Problem
By default, width and height only size the content area. Padding and border are added on top of that size — making elements larger than expected:
/* ❌ Default: box-sizing: content-box */
.box {
width: 300px;
padding: 20px; /* Adds 40px total */
border: 5px solid; /* Adds 10px total */
/* Actual rendered width: 300 + 40 + 10 = 350px ← SURPRISE */
}
3. box-sizing: border-box — The Fix
With border-box, the width property includes padding and border. The content area shrinks to compensate:
/* ✅ With border-box: 300px is the TOTAL width */
.box {
box-sizing: border-box;
width: 300px;
padding: 20px; /* Content shrinks to 260px, total stays 300px */
border: 5px solid; /* Content shrinks to 250px, total stays 300px */
}
Apply Globally (Always Include in Reset)
*,
*::before,
*::after {
box-sizing: border-box;
}
This is a universal best practice — every professional CSS project starts with this.
4. Content-Box vs Border-Box Side by Side
| Property | content-box (default) | border-box |
|---|---|---|
width: 300px | Content = 300px | Total = 300px |
+ padding: 20px | Total width = 340px | Content = 260px |
+ border: 5px | Total width = 350px | Content = 250px |
| Rendered width | 350px | 300px |
5. Computing Total Space
Even with border-box, margin is always added outside — never inside the declared width:
.card {
box-sizing: border-box;
width: 300px; /* Content: auto-fitted */
padding: 20px; /* Included in 300px */
border: 1px solid; /* Included in 300px */
margin: 20px; /* ADDED outside — total space = 300 + 40 = 340px */
}
6. Intrinsic vs Extrinsic Sizing
| Sizing Type | Keyword | Behavior |
|---|---|---|
| Extrinsic | width: 300px | Fixed size regardless of content |
| Intrinsic | width: max-content | Size based on content, no wrapping |
| Intrinsic | width: min-content | Smallest size before overflow |
| Intrinsic | width: fit-content | Like max-content, capped at available space |
.tag { width: fit-content; padding: 0.25rem 0.75rem; } /* Wraps content exactly */
.full { width: min-content; } /* Collapses to smallest possible width */
7. The Box Model in DevTools
In Chrome DevTools (Ctrl+Shift+I, then select an element), the Computed tab shows the box model diagram visually with exact pixel values for margin, border, padding, and content dimensions. This is your primary debugging tool for sizing issues.
8. Block Formatting Context (BFC)
A BFC is an independent rendering region where the normal block layout rules apply. Creating one prevents certain layout issues like margin collapsing and float containment:
.bfc { overflow: hidden; } /* Creates BFC — classic approach */
.bfc { display: flow-root; } /* Creates BFC — modern, no side effects */
.bfc { display: flex; } /* Also creates BFC */