Skip to main content

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 width and height.
  • 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, and color.
  • 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

Propertycontent-box (default)border-box
width: 300pxContent = 300pxTotal = 300px
+ padding: 20pxTotal width = 340pxContent = 260px
+ border: 5pxTotal width = 350pxContent = 250px
Rendered width350px300px

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 TypeKeywordBehavior
Extrinsicwidth: 300pxFixed size regardless of content
Intrinsicwidth: max-contentSize based on content, no wrapping
Intrinsicwidth: min-contentSmallest size before overflow
Intrinsicwidth: fit-contentLike 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 */