Problem Solved

CSS · box model

Home › Courses › CSS › Problems › Box model
🎨 Concept · 3 min read

The CSS box model.
Content, padding, border, margin.

Every element on a webpage is a rectangular box. The box has four layers — content, padding, border, margin — and understanding how they stack is the foundation of CSS layout. Set width: 200px and get an element that's 244px wide? That's the box model. Set padding: 20px and the layout jumps? Box model. This page covers all four layers, why the default trips people up, and the one CSS rule that fixes 90% of layout bugs.

Short answer: The box model has four layers from inside out: content, padding, border, margin. By default, width and height size the content only — padding and border add to the total. Fix with box-sizing: border-box, which makes width include padding and border. Add the universal reset *, *::before, *::after {'{ box-sizing: border-box; }'} to every stylesheet. It's not the CSS default, but it should be.

✅ The four layers

Inside out, with what each one does.

Content

The text, image, or child elements. Sized by width and height in content-box mode.

Padding

Space between content and border. Has the element's background color. Inside the clickable area for links and buttons.

Border

The line around the padding and content. Has its own width, style, and color. Adds to the total element size.

Margin

Space outside the border. Transparent. Pushes other elements away. Collapses with adjacent margins (vertical only).

✅ Before and after

The same declaration, two box-sizing modes.

content-box.css
.box {
box-sizing: content-box; /* default /
width: 200px;
padding: 20px;
border: 2px solid black;
margin: 10px;
}
Content width: 200px
Padding: +20px left + 20px right = +40px
Border: +2px left + 2px right = +4px
Margin: +10px left + 10px right = +20px (outside)

Total visible width: 200 + 40 + 4 = 244px
Total space taken: 244 + 20 = 264px

❌ You set width: 200px, you got 244px.
❌ Setting width: 156px would give you 200px.
❌ Confusing, error-prone, easy to break.
border-box.css
.box {
box-sizing: border-box; /* what you want /
width: 200px;
padding: 20px;
border: 2px solid black;
margin: 10px;
}
Total width: 200px (including padding and border)
Content width: 200 - 40 - 4 = 156px (auto-computed)
Margin: +10px left + 10px right = +20px (outside)

✅ width: 200px means 200px. Always.
✅ Adding padding shrinks the content, not the total.
✅ Layout math stays predictable.

⚠️ Margin is still outside — not included in width.
The element takes 220px of horizontal space
(200 + 20 margin), but the visible box is 200px.

✅ The universal fix

One rule. Every stylesheet. First line.

universal.css
/* The universal box-sizing reset */
*,
*::before,
*::after {
box-sizing: border-box;
}

/* Then your normal styles /
.header { padding: 2rem; }
.card { padding: 1rem; border: 1px solid #ddd; }
 → every element
*::before → pseudo-elements (::before, ::after)
*::after → pseudo-elements (::before, ::after)

Without ::before/::after in the selector,
pseudo-elements keep content-box — causing
inconsistent sizing for icons, decorations,
and the classic clearfix.

This 5-line rule appears in normalize.css,
reset.css, and almost every modern framework.
It's not the CSS default, but it should be.

Don't use box-sizing: border-box only on some elements. Either set it globally (via *, *::before, *::after) or don't set it at all. Mixing border-box on some elements and content-box on others means every layout calculation needs to know which mode applies where — and it will be wrong somewhere. The universal rule is the standard: set it once at the top of the stylesheet, forget about it, and every width in the codebase means the same thing.

⚠️ Common mistakes

The box-model mistakes that cost real time.

1. Not setting box-sizing globally

Padding and border add to width. Fix: universal border-box reset.

2. Forgetting ::before and ::after

Pseudo-elements keep content-box. Fix: include them in the universal selector.

3. Confusing padding and margin

Padding is inside (has background); margin is outside (transparent). Fix: padding for internal space, margin for external.

4. Expecting vertical margins to add

Adjacent vertical margins collapse. Fix: use padding, or wrap in a flex/grid container.

5. Setting width: 100% with padding

In content-box, this overflows the parent. Fix: border-box, or subtract padding from width.

6. Clicking on margin doesn't activate the element

Margin is outside the clickable area. Fix: use padding when you want more click area.

7. Percentage width + padding overflow

Same as 100% — content-box adds padding on top. Fix: border-box.

8. Expecting margin to collapse in flexbox

Flex items don't collapse margins. Fix: use gap for spacing in flex/grid containers.

❓ Frequently asked

What is the CSS box model?

Every element on a webpage is a rectangular box with four layers. From inside out: content, padding, border, margin. These four layers make up the box model. When you set width: 200px in default content-box mode, you're only sizing the content layer — padding and border add to the total width. That's the source of most layout confusion.

What does box-sizing: border-box do?

It changes how width and height are calculated. With content-box (the default), width sets the content size — padding and border add on top, so a div with width: 200px, padding: 20px, border: 2px is actually 244px wide. With border-box, width sets the total visible width — the browser shrinks the content area to fit padding and border inside the 200px. The element is exactly 200px wide regardless of padding.

Should I always use box-sizing: border-box?

Yes. The universal rule — *, *::before, *::after { box-sizing: border-box; } — is in virtually every modern stylesheet. It makes padding and border additive-safe. The only reason not to use it is if you're maintaining a legacy codebase that assumes content-box, in which case a global switch would break layouts. For new projects, always use border-box.

What is the difference between padding and margin?

Padding is inside the element — between content and border. Margin is outside the element — between the border and neighbors. Padding has the element's background color. Margin is always transparent. Padding is inside the clickable area (for links, buttons). Margin is outside. Padding does not collapse with adjacent elements. Margin does collapse. That last point is why padding is safer for vertical spacing between elements that might be adjacent.

Why is my element wider than I set?

Because box-sizing: content-box is the default — width sets only the content area, and padding/border add to the total. If you set width: 200px, padding: 20px, border: 2px, the actual width is 200 + 20 + 20 + 2 + 2 = 244px. Fix: add box-sizing: border-box to the element (or globally) — then width: 200px is the total width.

What is margin collapse?

When two vertical margins touch (adjacent siblings, parent and first child, or an empty element), they collapse into a single margin whose size is the larger of the two. Two divs each with margin-bottom: 20px and margin-top: 20px have 20px of space between them, not 40px. Margin collapse doesn't apply to padding, borders, horizontal margins, or flex/grid items. It's a spec behavior, not a bug.

🔗 Related

← All CSS problems
Problem solved · CSS