The CSS box model
Reason precisely about content, padding, border, and margin — and how box-sizing changes what 'width' means.

WHAT YOU WILL BE ABLE TO DO
Learning outcomes
- Explain the css box model in plain language.
- Connect the behavior to the underlying browser or framework model.
- Implement the core pattern and reason through edge cases.
- Answer common follow-ups without relying on memorized phrases.
01Explain it simply
Every rendered element is a rectangular box made of four layered regions: content, padding, border, and margin, from the inside out. 'Width' and 'height' only describe the content box by default — box-sizing decides whether padding and border are added on top of that number or included inside it.
One-line definition: Reason precisely about content, padding, border, and margin — and how box-sizing changes what 'width' means.
02Mental model
Think of two competing box-sizing models: content-box, the default, sets width and height on the content only, so padding and border make the box bigger than the number you wrote; border-box sets width and height on content plus padding plus border combined, so adding padding never changes the box's total footprint. Margin always sits outside both models and can collapse between adjacent block boxes.
03Step by step
- Identify which of content, padding, border, or margin a given CSS property affects.
- Check whether box-sizing is content-box (default) or border-box.
- Remember margin is outside the box and can collapse with adjacent vertical margins.
- Use border-box globally so padding and border never surprise a layout's total size.
- Use browser dev tools' box model panel to inspect actual computed sizes when a layout looks wrong.
04Working example
* { box-sizing: border-box; }
.card { width: 300px; /* total width, including padding and border */ padding: 16px; border: 1px solid #ccc;}/* Rendered box is exactly 300px wide — padding and border are absorbed inside it. */With border-box, the 300px already accounts for the 16px padding and 1px border on each side, so the element's actual footprint is 300px. Without box-sizing: border-box, this same CSS would render a 334px-wide box — 300 plus 32px of padding plus 2px of border.
05Where it is used
- Grid or flex layouts where every child must fit an exact track width
- Card and button components where padding shouldn't fight a fixed width
- Debugging 'why is my element wider than the container' bugs
- Establishing a global reset most teams apply on day one
06Common mistakes
- Forgetting box-sizing: border-box and being surprised a 100%-width element overflows once padding is added
- Confusing margin collapsing, which only applies between certain block-level vertical margins, with padding, which never collapses
- Assuming margin is 'inside' the box when it's actually outside both box-sizing models
- Setting a fixed height and being surprised when overflowing content breaks the layout instead of growing the box
07Interview answer
State which box-sizing model is active before answering any 'what's the actual size of this element' question — that's the detail that separates a real answer from a guess.
An element has width: 200px, padding: 20px, and box-sizing: content-box. What is its actual rendered width, ignoring border?
240px — content-box applies the width property to the content area only, so the 20px of padding on each side, 40px total, is added on top of the declared 200px.
DDConcept deep dives
Deep dive 1
Four regions, one box, two competing size models
content, padding, border, and margin nest from the inside out, and every layout bug involving unexpected size ultimately traces back to which of these four a property affects. box-sizing then decides whether the width and height you write describe just the content region (content-box) or the content-plus-padding-plus-border total (border-box) — the same declared width produces two different rendered sizes depending on this one property.
- Margin is always outside both models and never affects the box's own declared size.
- border-box is why adding padding to a fixed-width component doesn't break its layout.
- A global reset applying border-box removes an entire category of overflow bugs at once.
Deep dive 2
Margin collapsing is a block-formatting-context rule, not a general CSS behavior
Only adjacent vertical margins between certain block-level boxes in the same block formatting context can collapse into a single margin equal to the larger of the two. It doesn't apply to horizontal margins, to flex or grid item margins, or across a formatting-context boundary like a new block formatting context or a float. This scoped, easily-forgotten exception explains many 'why is there less spacing than I declared' surprises.
- Padding never collapses under any circumstance — only certain margins do.
- gap in flex/grid layouts sidesteps collapsing entirely by design.
- Establishing a new block formatting context (e.g. via overflow or display: flow-root) can stop unwanted collapsing.
Deep dive 3
box-sizing changes what a percentage or fixed width actually measures
A width: 100% or width: 300px declaration is resolved against the containing block first, then box-sizing decides whether that resolved number describes only the content box or the full outer box. This is precisely why a 100%-wide, padded content-box input can overflow its container while the identical CSS under border-box fits perfectly — the padding is either added on top of, or absorbed within, the same declared number.
- Debug overflow by checking box-sizing before assuming a layout or flex/grid bug.
- A component library's own reset can silently override a page-level reset — verify computed styles, not just source CSS.
- Border width also participates in the same content-box vs. border-box calculation as padding.
QAInterview questions and model answers
Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.
Beginner · Conceptual · 1 min · Question 1What are the four regions of the CSS box model, from inside out?Open model answer
Model answer
Content, padding, border, and margin. Content holds the element's actual content, padding is space inside the border, border is the visible edge, and margin is space outside the border that separates the box from its neighbors.
Open question page →Beginner · Coding · 1 min · Question 2What does box-sizing: content-box mean for the width property?Open model answer
Model answer
It means width and height apply only to the content area, so any padding and border you add are added on top of that number, making the rendered box larger than the declared width and height.
/* content-box (the default) */.box { box-sizing: content-box; width: 200px; padding: 20px; border: 5px solid; }/* rendered width = 200 + 20*2 + 5*2 = 250px */Beginner · Coding · 1 min · Question 3What does box-sizing: border-box change?Open model answer
Model answer
It makes width and height include content, padding, and border together, so adding padding or a border shrinks the available content area instead of growing the element's total footprint — this is why most resets apply it globally.
.box { box-sizing: border-box; width: 200px; padding: 20px; border: 5px solid; }/* rendered width = 200px; content area = 200 - 20*2 - 5*2 = 150px */
*, *::before, *::after { box-sizing: border-box; } /* common reset */Beginner · Conceptual · 1 min · Question 4Does margin participate in either box-sizing model?Open model answer
Model answer
No. Margin is always outside both the content-box and border-box calculations; it affects spacing between elements and can collapse with adjacent block-level vertical margins, but it never changes the box's own declared size.
Open question page →Intermediate · Coding · 1 min · Question 5What is margin collapsing?Open model answer
Model answer
When two adjacent block-level elements' vertical margins meet — such as the bottom margin of one and the top margin of the next — they can combine into a single margin equal to the larger of the two, rather than adding together.
.a { margin-bottom: 30px; }.b { margin-top: 20px; }/* gap between .a and .b is 30px, not 50px */Intermediate · Conceptual · 1 min · Question 6Why do most teams apply a global box-sizing: border-box reset?Open model answer
Model answer
It makes sizing predictable: a component's declared width stays its actual width regardless of how much padding or border is later added, avoiding a common class of layout overflow bugs in nested or responsive components.
Open question page →Beginner · Conceptual · 1 min · Question 7Does padding accept negative values?Open model answer
Model answer
No. Unlike margin, padding cannot be negative — the CSS specification requires padding values to be zero or positive, since negative padding has no coherent geometric meaning.
Open question page →Advanced · Conceptual · 1 min · Question 8How does box-sizing interact with a percentage width?Open model answer
Model answer
A percentage width is still resolved against the containing block first under either model; box-sizing then determines whether that resolved pixel value represents the content area alone or the content-plus-padding-plus-border total.
Open question page →Advanced · Conceptual · 1 min · Question 9Do flex and grid item margins collapse the way block-level margins do?Open model answer
Model answer
No. Margin collapsing is specific to block formatting contexts; margins on flex items and grid items never collapse with each other, which is one reason gap is often preferred for consistent spacing in those layouts.
Open question page →Intermediate · Conceptual · 1 min · Question 10What established box-sizing before border-box became the common default reset?Open model answer
Model answer
content-box was the original CSS default, inherited from the specification's early design, and remains the default today unless explicitly overridden — border-box only became a common reset choice once its predictability advantages were widely recognized.
Open question page →SCScenario questions
Scenario 1
A 100%-width input inside a form starts overflowing its container the moment a designer adds 12px of padding for better touch targets.
- Check whether box-sizing is content-box or border-box on the input.
- Confirm that content-box is adding the padding on top of the 100% width.
- Apply box-sizing: border-box to the input, or globally via a reset.
- Verify the input's total footprint now matches its container again.
Reveal worked answer
This is the classic content-box symptom — 100% width plus added padding under content-box makes the rendered box wider than its container. I would apply box-sizing: border-box, ideally as part of a global *, *::before, *::after reset, so this class of bug doesn't recur across the rest of the form.