The Box Model

Content, Padding, Border, Margin — In That Order

The Box Model

Every element is a rectangle with four layers. Master the box model — and switch on `box-sizing: border-box`.

5 min read Level 2/5 #css#box-model#border-box
What you'll learn
  • Read the four layers of the box model
  • Know what `box-sizing: border-box` does
  • Recognize margin collapse

Every CSS element is a rectangle with four concentric layers, from innermost out:

  1. Content — the actual content area (width × height)
  2. Padding — space INSIDE the border, around the content
  3. Border — the visible edge
  4. Margin — space OUTSIDE the border, between this and its neighbors
   ┌───────────────── margin ─────────────────┐
   │  ┌────────────── border ──────────────┐  │
   │  │  ┌─────────── padding ──────────┐  │  │
   │  │  │                              │  │  │
   │  │  │           content            │  │  │
   │  │  │                              │  │  │
   │  │  └──────────────────────────────┘  │  │
   │  └────────────────────────────────────┘  │
   └──────────────────────────────────────────┘

The Layers Are Independent

.card {
  width: 300px;
  padding: 20px;
  border: 2px solid black;
  margin: 16px;
  background: tomato;     /* the content+padding area */
}
  • The colored area = content + padding
  • The total visual width = width + 2×padding + 2×border = 344px
  • The total space taken = visual width + 2×margin

The box-sizing Gotcha

By default, width: 300px sets the content width. Padding and border push the total bigger — which is rarely what you want.

The fix:

*, *::before, *::after {
  box-sizing: border-box;
}

With border-box, width: 300px is the total width INCLUDING padding and border. Way more intuitive.

This belongs at the top of every stylesheet. Most resets and frameworks set it already.

Shorthand Margin / Padding

margin: 10px;                /* all four sides */
margin: 10px 20px;           /* top/bottom 10, left/right 20 */
margin: 10px 20px 30px;      /* top 10, sides 20, bottom 30 */
margin: 10px 20px 30px 40px; /* top, right, bottom, left (clockwise) */

Or per-side:

margin-top: 10px;
margin-inline: 20px;     /* left and right (logical property) */

Margin Collapse

A weird CSS quirk: vertical margins of adjacent block elements collapse to the larger of the two — not the sum.

.a { margin-bottom: 30px; }
.b { margin-top: 20px; }
/* Gap between .a and .b: 30px (not 50). */

Margin collapse happens with:

  • Vertical margins of block siblings
  • An element’s top/bottom margin with its parent’s
  • Empty elements’ top/bottom margins

It doesn’t happen:

  • Horizontally
  • For flex/grid children
  • When there’s a border, padding, or overflow between them

If margin collapse is biting you, the easiest fix is to use gap (in flex/grid) or set padding instead of margin on the parent.

Negative Margins

Margins can be negative. Sometimes useful for overlapping elements or pulling content into a container’s padding.

.card-image {
  margin: -1rem -1rem 0;   /* extend image to the card's edges */
}

Up Next

Colors — hex, rgb, hsl, modern formats.

Colors →