The Box Model & box-sizing

Every element is a box. Content, padding, border, and margin layer outward, and box-sizing controls what width actually measures.

CSS5 min readConcept 5 of 43

Four layers around every element

The **content area** is the innermost rectangle: where text and child elements live. Its dimensions are set by width and height.

**Padding** is transparent space between the content and the border. It inherits the element's background. **Border** is a line (with its own color, style, and width) drawn outside the padding. **Margin** is transparent space outside the border, separating the element from its neighbors. Margins do not take the element's background.

In the default box-sizing: content-box model, the width and height you set apply to the content area alone. Total rendered width = width + padding-left + padding-right + border-left + border-right. This makes arithmetic painful.

box-sizing: border-box makes sizing predictable

With border-box, width includes padding and border. If you set width: 300px; padding: 20px; border: 2px solid, the element is still exactly 300px wide. The content area shrinks to 256px to accommodate padding and border.

This is why nearly every modern CSS reset (and Tailwind) applies *, *::before, *::after { box-sizing: border-box; } globally. You almost never want content-box on anything that has both padding and a fixed width.

Working with the box model

Set padding and margin individually (padding-top, margin-left) or with shorthand. Shorthand accepts 1-4 values: padding: 8px (all sides), padding: 8px 16px (top/bottom, left/right), padding: 8px 16px 4px 12px (top, right, bottom, left, clockwise from top).

Use box-sizing: border-box via a global reset. Then width: 100% means the full parent width including padding, exactly as you would expect.

**Margin collapse:** when two block elements stack vertically, their adjacent margins collapse into one (the larger of the two). This does not happen in flex or grid containers, or when there is padding or border between parent and child.

**Outline** is similar to border but draws outside the element without affecting layout. It does not participate in the box model and will not push other elements around. Use it freely for focus rings.

Try it

Drag the padding, border, and margin sliders and watch the box model layers resize. Toggle border-box to see how it reflows.

Box model controls

Box model diagram

margin 16px
border 4px
padding 20px
content200px

Rendered width calculation

declared width:200px
+ padding (x2):+40px
+ border (x2):+8px
total width:248px

Check yourself

Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.

  1. 1An element has `width: 200px; padding: 20px; border: 5px solid black; box-sizing: content-box`. What is its total rendered width?
  2. 2Same element, now with `box-sizing: border-box`. What is its total rendered width?
  3. 3Two vertically stacked block elements: the top has `margin-bottom: 24px`, the bottom has `margin-top: 16px`. What is the gap between them?

Remember this

  • Box model layers outward: content + padding + border + margin.
  • content-box (default): width = content only. Total = width + padding + border.
  • border-box: width = content + padding + border. The total IS the width.
  • Adjacent vertical block margins collapse to the larger value. Does not happen in flex/grid.

Done with this concept?

Mark it complete to track your progress. No login needed.