The box model — what actually gets measured
Every element on a page is a box, and the box model is the exact rule for how that box's width and height get computed from content, padding, border, and margin — a rule that's silently different by default than most people assume.
3 min read
Four layers, from the inside out
.card {
width: 300px;
padding: 20px;
border: 2px solid #333;
margin: 10px;
}Every element's box has four concentric layers: content (the actual text/children, sized by width/height), padding (space inside the border, part of the element's own background), border (drawn right at the edge of padding), and margin (space outside the border, transparent, not part of the element itself — it just pushes neighboring elements away). Getting confident with CSS layout starts with being able to point at any visible gap on a page and say with certainty which of these four layers is causing it.
The default that surprises almost everyone: width doesn't mean total width
.card {
width: 300px;
padding: 20px;
border: 2px solid #333;
/* By default (content-box): total rendered width = 300 + 20*2 + 2*2 = 344px,
NOT 300px — width only sets the CONTENT box, padding and border are added on top */
}The default box-sizing: content-box means width/height set the size of the content layer only — padding and border get added on top of that, so a 300px-wide box with 20px padding and a 2px border actually renders at 344px wide. This surprises nearly everyone the first time they hit it: a grid of "300px cards" with padding doesn't actually line up at 300px intervals, because each card is quietly wider than its declared width.
The fix nearly every modern stylesheet applies globally
*, *::before, *::after {
box-sizing: border-box; /* width/height now include padding AND border */
}With box-sizing: border-box, width: 300px means the total rendered width is 300px — padding and border are subtracted from the content area internally instead of added on top, so the box actually measures what its width declares. This single global rule is one of the most universally-adopted resets in modern CSS, precisely because content-box's default behavior is almost never what anyone actually wants when laying out a grid of same-sized boxes.
Margin collapsing: two adjacent vertical margins can merge into one
.paragraph { margin-bottom: 20px; }
.paragraph + .paragraph { margin-top: 30px; }
/* The actual gap between two paragraphs is 30px (the LARGER of the two),
NOT 50px (20 + 30) — this is margin collapsing, and it only happens
for adjacent VERTICAL margins on block-level elements, never horizontal */When two block-level elements' vertical margins meet with nothing between them, they don't add together — they collapse into a single margin equal to the larger of the two. This is a real, specific CSS rule (not a bug), and it's a common source of "why is this gap smaller than I calculated" confusion, since intuition (treating margins like padding, which never collapses) says they should simply add.
Further reading
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. By default (content-box), what does a `width: 300px` element with `padding: 20px` and `border: 2px` actually render at?
2. What does `box-sizing: border-box` change about how width is measured?
3. What is margin collapsing?