CSS Box Model
Content, padding, border, margin, box-sizing, and how the math actually works for layout and overflow.
- css
- box-model
- layout
- box-sizing
Every element is a box. Layout, overflow, click targets, and “why is this 20px wider than I said?” all come back to the box model: content + padding + border + margin, plus which of those count toward width / height.
Docs: MDN CSS box model, MDN box-sizing, web.dev Learn CSS — The box model.
The four layers
From inside out:
| Layer | Role |
|---|---|
| Content | Text, images, or the area sized by width / height |
| Padding | Space inside the border, still part of the element’s background |
| Border | Edge drawn around padding + content |
| Margin | Space outside the border; collapses with sibling margins in normal flow |
.card {
width: 300px;
padding: 16px;
border: 2px solid #333;
margin: 24px;
}
With the default box-sizing: content-box, width: 300px means content only. The used outer width is roughly:
300 + 16×2 + 2×2 = 336px (before margin). Margin is outside the border box and does not add to the element’s own border-box size, but it does consume space in the layout.
content-box vs border-box
/* Default in CSS: content-box */
.box-a {
box-sizing: content-box;
width: 200px;
padding: 20px;
border: 5px solid;
/* border-box width ≈ 200 + 40 + 10 = 250px */
}
/* Almost always what you want in UI work */
.box-b {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid;
/* border-box width = 200px; content shrinks to fit */
}
border-box makes width / height include content + padding + border. Percent widths and grid/flex tracks stop “growing” when you add padding. Most design systems set this globally:
*,
*::before,
*::after {
box-sizing: border-box;
}
Some teams put it on html { box-sizing: border-box; } and inherit with *, *::before, *::after { box-sizing: inherit; } so third-party widgets can opt out. Either approach is fine; the point is predictable math.
Which box are you talking about?
When APIs and DevTools say “width,” they may mean different boxes:
| Term | Includes |
|---|---|
| Content box | Just content |
| Padding box | Content + padding |
| Border box | Content + padding + border |
| Margin box | Border box + margin |
getBoundingClientRect()→ border box (viewport coordinates)offsetWidth/offsetHeight→ border box (layout pixels, integers)clientWidth/clientHeight→ padding box minus scrollbarsscrollWidth/scrollHeight→ full scrollable content size
Reading these after style changes can force layout — see the rendering pipeline. Don’t thrash offsetHeight in a loop.
Margin collapse (normal flow)
Vertical margins of block-level elements in normal flow can collapse into one margin: the larger of the two wins (with rules for negative margins). Classic surprise:
.section {
margin-block: 2rem; /* 32px top and bottom… */
}
.section + .section {
/* …but adjacent siblings collapse: gap is 32px, not 64px */
}
Collapse does not apply the same way for flex/grid items, floated elements, or absolutely positioned boxes. If two sections suddenly have “half the gap you expected,” check collapse before blaming the cascade.
Parent/first-child collapse is another trap: a child’s top margin can stick out of a parent with no padding/border/overflow other than visible. Fix with padding, border, or display: flow-root (new BFC) on the parent.
Padding, borders, and hit areas
- Padding increases the clickable area of buttons and links — good for touch targets.
- Borders sit inside the border box under
border-box, so a1pxborder change can reflow neighbors if you didn’t reserve space (outlineor transparent border placeholders avoid layout jump). outlinedoes not take space in the box model — preferred for focus rings when you want no layout shift (outline vs border).
Inline vs block boxes
Inline-level boxes (span, a without display: block) still have padding and borders, but vertical margins don’t create the same block spacing, and width / height often don’t apply the way they do on blocks. For “chip” UI, use inline-flex or inline-block so the box model matches what designers expect.
.chip {
display: inline-flex;
align-items: center;
padding: 0.25rem 0.75rem;
border: 1px solid var(--border);
border-radius: 999px;
}
Overflow and the content box
overflow clips or scrolls the padding edge (overflow is defined relative to the padding box). Common layout bug in flex/grid: a child with long text won’t shrink below its min-content size, so the parent overflows even with overflow: auto. Pair with min-width: 0 on flex/grid children — covered in Flexbox fundamentals.
.panel {
display: flex;
min-height: 0;
}
.panel__body {
flex: 1;
min-width: 0;
overflow: auto;
}
Percentage padding and margin
Percentage padding and margin on physical properties are resolved against the width of the containing block (including vertical padding in classic CSS). That odd rule is why “padding-top: 56.25%” used to fake 16:9 ratios before aspect-ratio. Prefer aspect-ratio for media slots — fewer box-model hacks, better for CLS.
Debugging checklist
- In DevTools, inspect box model diagram (content / padding / border / margin).
- Confirm
box-sizingon that element (inherited globals can surprise you). - Is the surprise width from padding/border under
content-box? - Is vertical space “missing” because of margin collapse?
- Is overflow from min-content size, not from “wrong width”?
- Did you measure the wrong box (
clientWidthvsoffsetWidth)?
Interview angle
Define content / padding / border / margin. Explain content-box vs border-box with one numeric example. Mention margin collapse for adjacent blocks and that flex/grid items don’t collapse the same way. Bonus: which box getBoundingClientRect reports.
Live coding: build a card at exactly 320px outer border-box with 24px padding and a 2px border — without calculator thrash — using border-box.
Related on this site
- Flexbox fundamentals
- Cascade & Specificity
- CSS Grid fundamentals
- Position: static, relative, absolute, fixed, sticky
- Browser rendering pipeline
- Core Web Vitals
Further reading
- MDN: Introduction to the CSS box model
- MDN: Mastering margin collapsing
- MDN:
box-sizing - web.dev: The box model
- CSS Box Model Module Level 3
Related guides
- box-sizing border-boxWhy border-box makes width include padding and border, the global reset pattern, and the layout bugs content-box still causes.
- CSS Grid FundamentalsTwo-dimensional layout with tracks, gaps, placement, fr units, and when grid beats flex for page scaffolding.
- CSS Grid vs Flexbox When to UseOne-dimensional flex vs two-dimensional grid — decision rules for navs, card grids, page shells, and nested layouts.
- Display Block Inline Flex GridHow display changes layout participation — block vs inline vs inline-block, and when flex/grid formatting contexts take over.
- Flexbox FundamentalsFlex container vs items, main vs cross axis, grow/shrink/basis, alignment, wrapping, and the bugs that show up in real layouts.