LayoutBeginner8 min05 / 9

The Box Model

Every element on the page is a box — and understanding its four layers (content, padding, border, margin) is the key to controlling layout with confidence.

Have you ever tried to space things out on a page and felt like the browser was playing tricks on you? Elements overlapping, gaps that seem wrong, sizes that don't add up. The culprit is almost always a misunderstanding of the CSS Box Model — and once you grasp it, layout starts to feel logical rather than mysterious.

Every single element on a web page — a heading, a button, a paragraph — is rendered by the browser as a rectangular box with four distinct layers: content, padding, border, and margin. Learning what they do is the single most important concept in CSS layout.

Think of it like

Think of a framed painting on a wall

  • Content — the painting itself.
  • Padding — the white mat board between the painting and the frame, giving the artwork breathing room.
  • Border — the physical frame around the mat.
  • Margin — the empty wall space between this frame and the one hanging beside it.

The painting never touches the frame directly; the mat is in between. And the frame never touches the neighbouring painting; the wall gap separates them. That is exactly how CSS boxes work.

Each of the four layers maps to its own CSS property. You can set all four independently.
.card {
  width: 300px;           /* content area width */
  height: 150px;          /* content area height */
  padding: 20px;          /* space inside, between content and border */
  border: 2px solid #333; /* line drawn around the box */
  margin: 24px;           /* space outside, pushing neighbours away */
}

#What width Actually Controls (and Why It Surprises People)

By default, width and height set the size of the content area only — padding and border are added on top, making the element larger than you specified. With the styles below, the box occupies 250 px of horizontal space on screen — not 200 px:

Default (content-box) model: padding and border grow the outside of the element.
.box {
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
/* Rendered width: 200 + 20 + 20 + 5 + 5 = 250 px */
box-sizing: border-box — padding and border are included in width. This is so useful that Tailwind CSS and Bootstrap apply it by default. Add it to every project you create.
/* Add this reset at the very top of every stylesheet */
*,
*::before,
*::after {
  box-sizing: border-box;
}

.box {
  width: 200px; /* now the true total rendered width */
  padding: 20px;
  border: 5px solid black;
  /* content area shrinks to 150 px automatically */
}
Tip

Always start with the border-box reset

The *, *::before, *::after { box-sizing: border-box; } snippet is the first thing to put in every new stylesheet. Without it, adding padding or a border will silently grow your elements and break your layout in ways that are frustrating to debug.

#Padding vs. Margin — and the Collapse Gotcha

Both create space, but they behave very differently:

  • Padding is inside the border — it shares the element's background colour, and clicking in the padded area still counts as clicking the element.
  • Margin is outside the border — always transparent, it pushes neighbouring elements away.

You can set each side independently, or use shorthand. Values go clockwise: top, right, bottom, left:

``css .box { padding: 10px 20px; /* top+bottom 10px, left+right 20px */ margin: 16px 8px; /* top+bottom 16px, left+right 8px */ } ``

Common mistake

Vertical margins collapse — they don't add up

When two block elements are stacked vertically and both have vertical margins, CSS takes the larger of the two as the gap — not the sum. This is called margin collapse.

If a heading has margin-bottom: 24px and a paragraph below has margin-top: 16px, the actual gap is 24 px, not 40 px.

Only vertical (top/bottom) margins collapse. Left and right margins always add up normally.

Workaround: use padding on a parent container, or switch to a flex or grid layout, which disables margin collapse between items.

Quick check

You set an element's width to 400px, padding to 30px, and border to 5px — with no box-sizing reset applied. How wide does the element appear on screen?

Putting it all together: a practical card using every layer of the box model deliberately.
*,
*::before,
*::after { box-sizing: border-box; }

.card {
  width: 320px;           /* total rendered width */
  padding: 24px;          /* inner breathing room */
  border: 1px solid #ddd; /* subtle outline */
  margin: 32px auto;      /* centred, 32 px gap above and below */
  background-color: white;
  border-radius: 8px;
}

.card h2 {
  margin-top: 0;     /* kill default top margin — padding handles it */
  margin-bottom: 12px;
}

.card p { margin: 0; line-height: 1.6; }

Key takeaways

  • Every HTML element is a box with four layers from inside out: content, padding, border, and margin.
  • By default, width and height cover only the content area — padding and border are added on top, growing the element.
  • Add box-sizing: border-box globally so that width means the total rendered size. Do this on every project.
  • Padding is inside the border (shares the background); margin is outside (always transparent) and pushes neighbours away.
  • Vertical margins between block elements collapse — the larger value wins instead of both adding together.
Practice challenges
Test yourself · earn XP
0/4
Predict the output#1

With no box-sizing reset applied, how wide does this element actually appear on screen?

predict-output
.box {
  width: 200px;
  padding: 20px;
  border: 5px solid black;
}
Fill in the blank#2

Complete the reset so that width means the total rendered size, with padding and border carving into the content instead of growing the element.

*,
*::before,
*::after {
  box-sizing: ;
}
Fix the bug#3

This code has a bug — what's wrong?

fix-bug
.box {
  padding: 10px 20px;
  margin-collapse: none;
}
Predict the output#4

A heading has margin-bottom: 24px and the paragraph directly below it has margin-top: 16px. Both are block elements stacked vertically. What is the actual gap between them?

predict-output
h2 { margin-bottom: 24px; }
p  { margin-top: 16px; }
Your turn
Practice exercise

Build a styled profile card using the full box model. Create a .profile-card element that: (1) applies box-sizing: border-box globally, (2) has a fixed width of 360px, (3) has 32px of padding on all sides, (4) has a 2px solid border in a colour of your choice, (5) is centred on the page horizontally using margin auto, and (6) has a border-radius of 12px. Inside the card, make sure the h2 has no top margin so it sits flush against the inner padding.

Try it live — edit the code and hit Run to see it rendered:

solution.css · editable