Every single element on a web page is, visually, a rectangular box — and the CSS box model is the set of rules that determines how big that box actually is. It's one of the first things that trips up CSS beginners, because padding and borders don't behave the way most people initially assume.

The Four Layers

Every box is made of four layers, from the inside out: content (the actual text or image), padding (space between the content and the border), border (a visible or invisible line around the padding), and margin (space outside the border, separating this box from its neighbors).

.card {
  width: 300px;
  padding: 20px;
  border: 2px solid #ccc;
  margin: 16px;
}

This renders a box with content 300px wide, surrounded by 20px of padding, a 2px border, and 16px of margin pushing it away from whatever sits next to it.

The content-box Surprise

Here's the part that catches people out: by default, width: 300px sets the width of the content area only. The padding and border get added on top of that, making the box's actual rendered width larger than 300px.

/* Default box-sizing: content-box */
.card {
  box-sizing: content-box; /* this is the default even if omitted */
  width: 300px;
  padding: 20px;
  border: 2px solid #ccc;
}
/* Actual rendered width: 300 + 20 + 20 + 2 + 2 = 344px */

This box ends up 344px wide on screen, not 300px — the padding (20px on each side) and border (2px on each side) are added to the content width you specified. This becomes a real problem the moment you try to fit boxes into a layout by width: your math is wrong unless you account for every layer.

Fixing It with border-box

.card {
  box-sizing: border-box;
  width: 300px;
  padding: 20px;
  border: 2px solid #ccc;
}
/* Actual rendered width: exactly 300px */

With box-sizing: border-box, the width you set becomes the total width of content + padding + border combined — the browser shrinks the content area to make room for padding and border, instead of adding them on top. This matches how most developers intuitively expect width to work, which is why it's become the near-universal default in modern CSS resets:

*, *::before, *::after {
  box-sizing: border-box;
}

This one rule, applied once at the top of a stylesheet, switches every element on the page to the more predictable sizing model — it's one of the first lines in almost every modern CSS file.

Margin Collapsing

One more quirk worth knowing: vertical margins between adjacent block elements don't add together — they collapse to the larger of the two values. A paragraph with margin-bottom: 20px followed by another with margin-top: 30px ends up with 30px of space between them, not 50px. Horizontal margins and margins in a flex or grid context don't collapse this way — it's specifically a vertical, block-layout behavior.

Understanding the box model is the foundation everything else in CSS layout builds on, from Flexbox to CSS Grid.