webdev.complete
💄 CSS — The Skin
🧱Foundations
Lesson 11 of 117
20 min

The Box Model

Margin, border, padding, content. Every element is a box.

Every element on a page is a box. Even the round avatars. Even the text. Even the things that look like nothing. The CSS box model describes how each of those boxes is constructed and how they push against each other. Master this and 80% of layout mysteries dissolve.

The four layers

Every box has four concentric rectangles. From innermost outward:

  1. Content - the actual text, image, or child elements.
  2. Padding - space inside the box, between content and border. Transparent. Inherits the background.
  3. Border - a line drawn around the padding. Can be colored, dashed, rounded.
  4. Margin - space outside the box, pushing other elements away. Always transparent.
Padding inside, margin outside
That's the one-sentence summary. Padding is the air between content and the edge of the box. Margin is the air between this box and its neighbors.

box-sizing: the most important reset

By default, when you set width: 300px, that's the width of the content only. Padding and border get added on top, making the actual box wider. This is almost never what you want.

css
/* Default: content-box */
.thing {
  width: 300px;
  padding: 20px;
  border: 2px solid;
  /* Actual rendered width: 344px (300 + 20 + 20 + 2 + 2) */
}

Switch to box-sizing: border-box and the width becomes the total box width, including padding and border. The content shrinks to fit.

css
/* Apply border-box to everything - the modern default */
*, *::before, *::after {
  box-sizing: border-box;
}

.thing {
  width: 300px;
  padding: 20px;
  border: 2px solid;
  /* Actual rendered width: 300px */
}

Margin collapse: the rule everyone trips on

Two vertical margins between sibling block elements collapse into one. The larger margin wins; they don't add up.

html
<p style="margin-bottom: 20px">First</p>
<p style="margin-top: 30px">Second</p>
<!-- The gap is 30px, not 50px -->

It also collapses with the parent: if a child has margin-topand the parent has no padding or border, the child's margin pokes above the parent. This is a feature, not a bug, but it surprises every beginner.

Margin collapse only happens with vertical margins on block elements, and never inside flex or grid containers. Modern layouts using flex and grid sidestep it entirely.

Quick fix when margin collapse bites
Set display: flow-root on the parent, or use gap on a flex/grid container instead of margins on children. Both prevent the collapse.

Shorthand: one, two, three, or four values

padding and margin are shorthand for four sides. The number of values changes meaning:

  • padding: 10px; - all four sides.
  • padding: 10px 20px; - vertical | horizontal.
  • padding: 10px 20px 30px; - top | horizontal | bottom.
  • padding: 10px 20px 30px 40px; - top | right | bottom | left (clockwise from top).

Logical properties (the modern way)

margin-top and padding-leftare physical directions. They don't adapt to right-to-left languages like Arabic or vertical writing modes like traditional Japanese. Logical properties do.

  • margin-block-start / margin-block-end - top/bottom in horizontal text.
  • margin-inline-start / margin-inline-end - left/right in horizontal LTR text.
  • padding-block - shorthand for both block sides.
  • padding-inline - shorthand for both inline sides.
css
/* Old (physical): only works for LTR horizontal text */
.button {
  padding: 0.5rem 1rem;
  margin-left: 1rem;
}

/* New (logical): works for any writing mode */
.button {
  padding-block: 0.5rem;
  padding-inline: 1rem;
  margin-inline-start: 1rem;
}
Why bother?
On an Arabic site, the "start" of a line is the right side. If you wrote margin-left: 1rem, the spacing looks wrong when the language flips. margin-inline-start follows the text direction automatically.

Visualize it

Drag the sliders. Watch the layers grow and shrink. Notice how padding grows the box (with border-box, content shrinks instead). Notice how margin pushes away the dotted neighbor.

Box model live
Content area
Neighbor (notice margin pushes from this box)
.box {
  width: 220px;
  height: 110px;
  padding: 20px;
  border: 4px solid #1d4ed8;
  margin: 16px;
  box-sizing: border-box;
}

min/max and the modern sizing keywords

Width and height accept far more than fixed pixels:

  • auto - let the browser compute it.
  • 100% - fill the container.
  • min-content - as small as the content allows (the longest unbreakable word).
  • max-content - as wide as the content wants to be (no wrapping).
  • fit-content - somewhere between min and max; wraps but doesn't expand past the container.
  • min-width, max-width, min-height, max-height - boundaries.

A common, useful pattern: max-width: 60ch on body text. chis the width of the "0" character in the current font, so 60ch is a comfortable line of about 60 characters. The line stays readable on any screen.

Quick quiz

Quiz1 / 3

With box-sizing: content-box (the default), you set width: 200px, padding: 20px, border: 2px. What's the rendered width?

Recap

  • Every element is a box: content → padding → border → margin.
  • Set box-sizing: border-box globally. Width then includes padding and border. Sanity restored.
  • Margins collapse vertically between block siblings (and into their parent). Flex/grid gap sidesteps it.
  • Padding/margin shorthand: 1 value (all), 2 (vertical/horizontal), 4 (top/right/bottom/left).
  • Use logical properties (margin-block, padding-inline) for RTL and writing-mode resilience.
  • Width keywords: min-content, max-content, fit-content. Combine with max-width: 60ch for readable text.