The CSS Box Model,
completely explained.

If you can't explain it simply, you don't understand it well enough. Here's the box model explained like you're five — then like a pro.

Why does the Box Model exist?

When browsers were invented, designers needed a way to control where things go and how much space they take up. Without a system, every element would crash into every other.

The Box Model is that system. It gives every element a personal "bubble" of space — structured into four layers — so the browser always knows exactly how much room to reserve for it.

The Feynman Version

Imagine you're moving apartments. Every item you own needs its own shipping box. You can't just toss things loose in a truck — things would break. The Box Model is CSS's packing system. Content = your item. Padding = the foam inside. Border = the box itself. Margin = the space movers leave between boxes.

margin
border
padding
content text, images...

How browsers render elements

Every time a browser loads a page, it goes through a process called layout (or "reflow"). During layout, it asks: "Where should this element go, and how big should it be?"

The answer comes entirely from the Box Model. The browser calculates each element's box dimensions, stacks them according to the document flow, and paints them to screen.

1. Parse HTML
Browser reads your HTML and builds a tree of elements (the DOM).
2. Apply CSS
Styles are computed — including box model values from your CSS rules.
3. Layout / Reflow
Each element's box is calculated using content size + padding + border + margin.
4. Paint
Visual properties are drawn — backgrounds, borders, text, images.
5. Composite
Layers are assembled into the final image you see in your browser.

Understanding this helps you reason about performance. Changing a box model property like width or padding triggers a reflow — the browser must recalculate layout. Changing only background-color skips layout and goes straight to paint.

How width & height are calculated

This is where most beginners get confused. When you write width: 200px, does the element take up 200px? Not necessarily.

It depends on the box-sizing property. In the default mode (content-box), width only sets the content area width. Padding and border are added on top.

Default formula (content-box)
Total width = width + padding-left + padding-right + border-left + border-right
Total height = height + padding-top + padding-bottom + border-top + border-bottom

So if you set width: 200px, padding: 20px, and border: 5px solid, the element actually takes up:

Example calculation
200 + 20 + 20 + 5 + 5 = 250px total width
💡 Why this surprises people

You write width: 200px but the element is 250px wide. This catches designers off guard constantly. It's the most common "why is my layout broken" problem in CSS. The solution? Use box-sizing: border-box (see Section 08).

Padding in depth

Padding is the space inside the border, between the content and the edge of the element. Think of it as "internal breathing room."

Padding inherits the element's background color — so it visually looks like part of the element. You can click on padding; it responds to mouse events just like content.

No padding
Hello, I'm crammed in here!
padding: 0
With padding
I have room to breathe!
padding: 16px

Padding can be set on all four sides independently:

/* All four sides */
padding: 20px; /* all sides = 20px */
padding: 10px 20px; /* top/bottom=10, left/right=20 */
padding: 5px 10px 15px 20px; /* top right bottom left */

/* Individual sides */
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 20px;

Border in depth

The border sits between the padding and the margin. It's a visual frame around your element. Unlike padding (which is always transparent to background colors), border has its own color.

Every border has three required attributes: width, style, and color.

/* Shorthand */
border: 2px solid #333;

/* Individual properties */
border-width: 2px;
border-style: solid; /* solid, dashed, dotted, none... */
border-color: #333;

/* One side only */
border-bottom: 3px solid blue;

Remember: border adds to the element's total width and height in default (content-box) mode. A 2px border adds 4px to the total width (2px left + 2px right).

Common border styles
solid
dashed
dotted
double
groove

Margin & interactions with neighbors

Margin is the transparent space outside the border. It pushes other elements away. Unlike padding, margin cannot be clicked on and has no background color — it's always invisible.

Margin creates breathing room between elements. Use it to control how elements relate spatially to one another.

Without margin
Element A
Element B
margin: 0
With margin
Element A
Element B
margin-bottom: 16px

Margin accepts negative values, which pulls elements closer together (or even overlaps them). This is useful for advanced layout techniques.

margin: auto is a powerful trick for horizontal centering — the browser splits the remaining space equally on both sides.

/* Center a block element */
margin: 0 auto; /* top/bottom=0, left/right=auto */

/* Negative margin — pull elements together */
margin-top: -20px;

Margin collapsing

Here's one of CSS's most surprising behaviors: when two vertical margins meet, they collapse into one. The larger of the two margins wins — they don't add up.

⚠️ The Surprising Rule

Element A has margin-bottom: 30px. Element B has margin-top: 20px. You might expect 50px between them — but the actual gap is only 30px (the larger value wins). The margins collapse.

Element A
margin-bottom: 30px
30px gap
(not 50px!)
Element B
margin-top: 20px

Margin collapsing only happens vertically (top/bottom), not horizontally. It also only happens between block-level elements that are direct siblings or parent/child.

When does collapsing NOT happen? When there's a border, padding, or overflow property between parent and child, or when elements are flex/grid children.

Collapsing rule
gap = max(margin-bottom of A, margin-top of B)
— NOT margin-bottom + margin-top

content-box vs border-box

The box-sizing property fundamentally changes how width and height are calculated. It's one of the most important CSS properties to understand.

📦 content-box default

width applies only to the content area. Padding and border are added on top of the specified width.

width: 200px
Total: 200 + 20+20 + 5+5 = 250px
🎯 border-box recommended

width applies to the entire element including padding and border. The content shrinks to compensate.

width: 200px ← total
Total: always 200px

Most modern projects use this global reset at the top of their CSS to make everything predictable:

/* Modern CSS reset — apply to every project */
*, *::before, *::after {
  box-sizing: border-box;
}
The Simple Rule

Use border-box for everything. It makes sizing intuitive: width: 300px means the element is exactly 300px wide, no matter how much padding or border you add.

Take it back to the playground.

Use what you just learned. Drag sliders, watch the box change. Theory becomes intuition.

Open the Playground →