What is the CSS box model, and what is the difference between content-box and border-box?

Beginner8 min interview
Skills tested:
Naming the four box model layers in order from inside outComputing an element rendered width under content-boxExplaining how border-box redefines the width propertyKnowing which box model layers are painted and which are transparentRecognising that margin sits outside the element background

Advertisement

🧩 Scenario

Every layout bug that ends with "why is my column 24px too wide" traces back to the box model. When you set a card to width: 25% and then add padding for breathing room, whether that padding pushes the card past its column depends entirely on which box-sizing mode is active. This is the first thing to reason about before reaching for calc() or negative margins.

Architecture Walkthrough

Four Layers, Inside Out

Every element the browser renders is a rectangular box composed of four concentric layers. The content box is innermost and holds the actual text, image, or child boxes. Wrapped around it is the padding box, transparent space that pushes content away from the edge. Around that sits the border box, a drawable frame with its own width, style, and colour. Outermost is the margin box, transparent space that separates this element from its neighbours.

The distinction that matters most in practice is where the background stops. Backgrounds and background images paint across the content and padding areas and, by default, extend under the border as well. They never paint into the margin. That is why margin is the right tool for spacing between elements and padding is the right tool for space inside a coloured or bordered element.

What the width Property Actually Sizes

Here is the part that surprises people: the width and height properties do not size the element. They size one specific layer of it, and which layer they size depends on box-sizing.

Under box-sizing: content-box, the CSS default, width sets the width of the content box only. Padding and border are then added on top. An element with width: 200px, padding: 20px, and a 5px border occupies 250px of horizontal space: 200 for content, 20 of padding on each side, and 5 of border on each side. Margin adds further space around that but is not part of the element box itself.

Under box-sizing: border-box, width sets the width of the border box, meaning it includes padding and border. That same declaration set produces an element exactly 200px wide on screen, with the content box shrinking to 150px to absorb the padding and border. The number you write is the number you get.

Why border-box Won

content-box is mathematically defensible but practically hostile. It means you cannot safely combine a percentage width with a pixel padding, because 25% + 32px overflows a four-column row. Developers worked around this for years with nested wrapper elements or calc(25% - 32px) gymnastics.

border-box removes the whole class of problem: percentages, padding, and borders compose without arithmetic. Because of that, essentially every modern reset, framework, and design system applies it globally. Tailwind's preflight does it, Bootstrap does it, and so does virtually every hand-rolled reset. Treat border-box as the practical default and content-box as legacy behaviour you should recognise but rarely choose.


Key Code Explained

/* content-box: width sizes the CONTENT only */
.content-box-card {
  box-sizing: content-box; /* the CSS default */
  width: 200px;
  padding: 20px;
  border: 5px solid #333;
  /* rendered width = 200 + 20 + 20 + 5 + 5 = 250px */
}

/* border-box: width sizes CONTENT + PADDING + BORDER */
.border-box-card {
  box-sizing: border-box;
  width: 200px;
  padding: 20px;
  border: 5px solid #333;
  /* rendered width = 200px exactly; content box shrinks to 150px */
}

/* The reset almost every project ships */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Why it matters: this only works under border-box */
.column {
  width: 25%;
  padding: 16px;
  /* content-box: 25% + 32px per column -> the fourth column wraps
     border-box: four columns fit perfectly, padding eats inward */
}

/* Margin is outside the box: no background, and it does not
   count toward the width under either box-sizing mode */
.spaced {
  box-sizing: border-box;
  width: 200px;
  margin: 24px;
  background: #eef; /* paints content + padding, never the margin */
}

The .column rule is the one worth memorising. It is the smallest possible demonstration of why the box model is not trivia: the exact same three declarations produce a working four-column row under one box-sizing value and a broken wrapping layout under the other. Nothing about the selector, the markup, or the parent changed.

The reset is worth reading closely too. It includes ::before and ::after because pseudo-elements are real boxes with their own box-sizing, and they do not inherit the value from their originating element the way you might expect from the * selector alone.


Tradeoffs

Aspectcontent-boxborder-box
What width sizesContent onlyContent + padding + border
Mixing % width with px paddingOverflows, needs calc()Composes cleanly
Rendered size predictabilityMust add layers mentallyEquals the declared value
Spec statusThe CSS defaultOpt-in via reset
When to prefer itRare: when content must be an exact size regardless of chromeEffectively always

What Interviewers Actually Check

  • Whether you can name all four layers in order and say which ones are transparent
  • Whether you can do the arithmetic for a rendered width under both box-sizing modes
  • Whether you understand that width sizes a layer, not the element
  • Whether you know margin sits outside the element and never receives the background
  • Whether you can explain why border-box became the de facto standard rather than just reciting that it is

Follow-Up Questions

  1. Does box-sizing: border-box change how margin participates in layout? Why or why not?
  2. What happens under border-box if padding and border together exceed the declared width?
  3. How does background-clip interact with the box model layers, and what are its three main values?
  4. Why do width and height have no effect on a non-replaced inline element like a <span>?
  5. How do min-width and max-width interact with box-sizing, and are they measured against the same box?

Common Candidate Mistakes

  • Assuming width: 300px guarantees a 300px footprint on screen, when under content-box any padding or border silently widens it
  • Adding padding to a percentage-width column and then blaming flexbox or grid when the row wraps, instead of checking box-sizing
  • Setting a background colour and expecting the margin area to be tinted, then adding a wrapper element to "fix" it rather than switching to padding
  • Applying box-sizing: border-box to one problem element instead of resetting it globally, which leaves the rest of the codebase inconsistent
  • Conflating the box model, which describes an element's internal geometry, with the visual formatting model, which decides how those boxes flow, stack, and align relative to each other

Interview Readiness Checklist

Before you leave this question, make sure you can answer:

  • Can you name the four layers of the box model from the inside out?
  • Can you compute the on-screen width of an element given width, padding, and border under both box-sizing modes?
  • Can you explain exactly which property border-box redefines?
  • Can you explain why margin never shows the element background colour?
  • Can you write the global border-box reset from memory, including the pseudo-element selectors?

Summary

The CSS box model describes every rendered element as four concentric layers: content, padding, border, and margin. Content and padding receive the background, the border is drawable, and the margin is transparent space outside the element that separates it from its neighbours. Understanding which layers are painted explains most of the day-to-day choice between padding and margin.

The width and height properties do not size the element as a whole; they size one layer, and box-sizing decides which. Under content-box, the CSS default, width sizes the content box and padding and border are added on top, so a 200px element with 20px padding and a 5px border renders 250px wide. Under border-box, width sizes the border box, so that same element renders exactly 200px wide and the content shrinks to absorb the chrome.

border-box is the practical default in modern CSS because it lets percentage widths, pixel padding, and borders coexist without calc() arithmetic. Nearly every reset and framework applies it globally to *, *::before, and *::after. Know content-box well enough to recognise its symptoms in legacy code, and reach for border-box everywhere else.

Frequently Asked Questions

Which box-sizing value is the CSS default?

content-box is the spec default. Almost every modern codebase overrides it with a global border-box reset, which is why developers often forget content-box exists.

Does the box model apply to inline elements too?

Partly. Inline elements honour horizontal padding, border, and margin, but width, height, and vertical margins have no effect on them. Use inline-block or a flex/grid child if you need full box control.

Advertisement


Stay Updated

Get the latest frontend challenges, interview questions and tutorials delivered to your inbox.

Advertisement