The Box Model

📦 Chapter 3 — The Box Model

Every single element on a webpage — a heading, a paragraph, an image, a button — is rendered by the browser as a rectangular box. The box model describes the four layers that make up that box and how they interact to determine the element's final size and spacing. Understanding the box model is not optional; it is the foundation every layout decision in CSS is built on. Get it wrong and nothing ever lines up the way you expect.

1 — The Four Layers

Every box is composed of four concentric layers, from the inside out: content, padding, border, and margin.

MARGIN BORDER PADDING Content width × height margin-top border-top padding-top
Content
The innermost layer — where text, images, and child elements live. Its size is controlled by width and height.
width · height
Padding
Transparent space between the content and the border. Increases the element's clickable area and visual breathing room. Takes the element's background colour.
padding · padding-top/right/bottom/left
Border
A visible (or invisible) line that wraps the padding and content. Has width, style, and colour. Sits between the padding and the margin.
border · border-width/style/color
Margin
Transparent space outside the border — pushes other elements away. Always transparent; never takes the element's background colour.
margin · margin-top/right/bottom/left

2 — Padding

Padding creates space inside the element, between its content and its border. It inherits the element's background colour, so it appears as part of the element visually.

🎨 CSS — Setting padding
/* Set each side individually */ .box { padding-top: 16px; padding-right: 24px; padding-bottom: 16px; padding-left: 24px; } /* Shorthand — one to four values */ .box { padding: 16px; } /* all four sides: 16px */ .box { padding: 16px 24px; } /* top+bottom: 16px | left+right: 24px */ .box { padding: 8px 16px 24px; } /* top: 8px | sides: 16px | bottom: 24px */ .box { padding: 8px 16px 24px 32px; } /* top right bottom left (clockwise) */

The shorthand order — clockwise from top

padding: top;
1 value — all four sides equal
padding: top/bottom left/right;
2 values — vertical | horizontal
padding: top left/right bottom;
3 values — top | sides | bottom
padding: top right bottom left;
4 values — clockwise from top
💡 The same shorthand pattern applies to margin. Once you know it for padding, you know it for margin too — the clockwise-from-top order is identical for both properties.

3 — Border

The border wraps the padding and content. It has three components: width (thickness), style (the line type), and colour. All three must be set — a border with no style is invisible.

🎨 CSS — Setting borders
/* Shorthand — width | style | colour */ .box { border: 2px solid #4f8ef7; } /* Longhand — set each property separately */ .box { border-width: 2px; border-style: solid; border-color: #4f8ef7; } /* Target individual sides */ .card { border: 1px solid #2a2d3a; /* thin border all around */ border-left: 4px solid #7ecfa0; /* thick accent on the left */ } /* Rounded corners */ .pill { border-radius: 999px; /* fully rounded (pill shape) */ } .card { border-radius: 6px; /* subtly rounded corners */ }

Border style values

ValueAppearanceCommon use
solidContinuous lineMost common — cards, inputs, dividers
dashedDashes with gapsDrop zones, placeholders, "add item" areas
dottedDots with gapsDecorative, focus rings
doubleTwo lines with a gapDecorative headings
noneNo borderRemoving browser default borders on buttons/inputs
border-radius works without a visible border. You can use border-radius to round the corners of an element's background even if it has no border. It clips the background (and any padding) to the rounded shape.

4 — Margin

Margin creates space outside the element, pushing other elements away. Unlike padding, margin is always fully transparent — it never takes the background colour of the element.

🎨 CSS — Setting margin (same shorthand as padding)
/* Individual sides */ .box { margin-top: 20px; margin-right: 0; margin-bottom: 20px; margin-left: 0; } /* Same as above — shorthand: top+bottom 20px, sides 0 */ .box { margin: 20px 0; } /* auto — centres a block element horizontally */ .container { width: 800px; margin: 0 auto; /* top+bottom: 0 | sides: auto (equal) */ } /* Negative margins — pull elements closer together */ .overlap { margin-top: -20px; /* overlaps 20px with the element above */ }
margin: 0 auto is one of the most-used CSS patterns — the standard way to horizontally centre a fixed-width block element on the page.

Margin collapse

One surprising behaviour: when two vertical margins touch — the bottom margin of one element and the top margin of the element below it — the browser does not add them together. Instead, it uses only the larger of the two. This is called margin collapse.

Margin collapse in action
Two elements both have a 20px margin on the touching edges. You might expect 40px of space between them — but the browser collapses it to 20px.
.box-a { margin-bottom: 20px; } .box-b { margin-top: 20px; } /* Gap between .box-a and .box-b is 20px, not 40px */ /* If box-a had margin-bottom: 30px, the gap would be 30px */
Margin collapse only happens vertically (top/bottom margins), never horizontally (left/right margins). It also does not happen inside flex or grid containers — another reason those layout methods are preferred for complex layouts.

5 — Width and Height

The width and height properties set the size of the content area — the innermost layer of the box. The element's rendered size on the page also includes padding and border on top of this.

🎨 CSS — Width and height
.box { width: 300px; /* fixed width */ height: 200px; /* fixed height */ } /* Constrain with min/max — useful for responsive designs */ .article { width: 100%; /* fills the parent */ max-width: 700px; /* but never wider than 700px */ min-width: 280px; /* and never narrower than 280px */ } /* Heights are often best left unset — let content decide */ /* min-height is safer than height for variable content */ .hero { min-height: 400px; }
Setting a fixed height on elements with variable content can cause text to overflow the box. Prefer min-height when you want a minimum size but need the box to grow with its content.

6 — box-sizing: The Critical Setting

By default, when you set width: 300px, the browser applies that 300px to the content area only. Padding and border are then added on top, making the element wider than 300px. This is called content-box sizing and is the source of countless layout bugs.

content-box (default — avoid)
width: 300px
padding: 20px (each side)
border: 2px (each side)
Rendered width = 300 + 40 + 4 = 344px ✗
border-box (use this — always)
width: 300px
padding: 20px (each side)
border: 2px (each side)
Rendered width = 300px exactly ✓

With box-sizing: border-box, padding and border are included in the declared width. What you set is what you get — the element is exactly as wide as you said.

🎨 CSS — The universal box-sizing reset (put this at the top of every stylesheet)
/* Apply border-box sizing to every element on the page */ *, *::before, *::after { box-sizing: border-box; }
Including ::before and ::after ensures the setting applies to CSS-generated pseudo-elements too. This reset is so universally useful that it is included in virtually every CSS framework and starter template.
⚠️ Never build a stylesheet without this reset. The content-box default was a design mistake from the early web. Every professional CSS codebase starts with the border-box reset. Make it a habit: first line of every stylesheet, before anything else.

7 — Calculating Total Element Size

Even with border-box set, you still need to account for margin when thinking about how much space an element occupies in the layout flow. Margin sits outside the box and always adds to the space the element takes up relative to its neighbours.

Space taken up in the layout flow
.card { box-sizing: border-box; width: 300px; /* the box is exactly 300px wide */ padding: 20px; /* included in the 300px */ border: 2px solid #4f8ef7; /* included in the 300px */ margin: 16px; /* OUTSIDE the 300px */ } /* Box width: 300px (border-box — padding + border absorbed) */ /* Total space in layout: 300 + 16 + 16 = 332px horizontally */

8 — Inspecting the Box Model in DevTools

Every browser's developer tools include a visual box model inspector. When you click an element in the Elements panel, a diagram shows its exact content, padding, border, and margin values — colour-coded identically to the diagram at the top of this chapter.

  • Chrome/Edge: Elements panel → select an element → scroll down in the Styles panel to find the box model diagram, or switch to the "Computed" tab.
  • Firefox: Inspector panel → select an element → "Box Model" section in the right panel.
  • Safari: Elements panel → select an element → "Computed" tab → Box Model section at the top.
💡 Use DevTools to debug spacing problems. When an element is not the size you expect, open the box model inspector immediately. You will instantly see whether the issue is unwanted padding, a margin collapse, an unexpected border, or the content-box sizing problem. Guessing wastes time — inspect first.

9 — Quick Reference

PropertyWhat it controlsKey values
paddingInner space (content → border)px, rem, %, auto — uses shorthand clock order
borderBorder around padding+contentwidth style color e.g. 2px solid red
border-radiusCorner roundingpx, %, 50% = circle, 999px = pill
marginOuter space (pushes other elements)px, rem, %, auto — same shorthand as padding
widthContent width (or total width with border-box)px, %, auto, 100%
heightContent heightpx, %, auto — prefer min-height for variable content
max-widthUpper width limitpx, % — commonly used with width: 100%
box-sizingWhether padding/border are included in widthborder-box (use always) / content-box (avoid)

✏️ Exercises

Start every exercise stylesheet with the box-sizing: border-box reset. Use your browser's DevTools box model inspector to verify your results — compare what you see on screen to what the inspector reports.

Exercise 1
Create a <div> with a fixed width of 400px and a fixed height of 200px. Give it a solid 3px border in a colour of your choice, 24px of padding on all sides, and 40px of margin at the top and bottom. Add a background colour so you can clearly see the padding area. Open DevTools and verify the box model matches what you set.
Hint: include the box-sizing: border-box reset at the top of your stylesheet. The box model inspector in DevTools should show exactly 400px width and 200px height.
CSS
* { box-sizing: border-box; } .demo-box { width: 400px; height: 200px; border: 3px solid #4f8ef7; padding: 24px; margin: 40px 0; background-color: #1a2e1a; }
Exercise 2
Build a simple notification bar. Create a full-width <div> with class="alert". It should have: 12px top/bottom padding and 24px left/right padding, a 4px left-only solid border in a warning colour (orange or yellow), a lightly tinted background to match the border colour, no top or bottom margin, and text that reads "⚠️ Your session will expire in 10 minutes."
Hint: use padding: 12px 24px for the two-value shorthand. Use border-left: 4px solid #e8a87d and a very faint matching background like #2a1e0a.
CSS
* { box-sizing: border-box; } .alert { width: 100%; padding: 12px 24px; border-left: 4px solid #e8a87d; background-color: #2a1e0a; color: #e8a87d; margin: 0; font-family: system-ui, sans-serif; }
Exercise 3
Create a centred article layout. Make a <div class="article"> that is 100% wide up to a maximum of 680px, centred horizontally on the page using margin: 0 auto, with 40px of padding on all sides. Give the page body a dark background and the article a slightly lighter background so the centring is visible. Put a few paragraphs of text inside so you can see the padding in action.
Hint: max-width: 680px combined with width: 100% and margin: 0 auto is the classic centred-column pattern. The body needs a min-height: 100vh or enough content to show the background.
CSS
* { box-sizing: border-box; margin: 0; padding: 0; } body { background-color: #0d0d0d; font-family: Georgia, serif; padding: 40px 20px; } .article { width: 100%; max-width: 680px; margin: 0 auto; padding: 40px; background-color: #1a1d27; border-radius: 8px; color: #e2e4ec; line-height: 1.75; }
Exercise 4
Demonstrate the difference between content-box and border-box. Create two <div> elements side by side, both with width: 300px, padding: 20px, and border: 4px solid. Apply box-sizing: content-box to the first and box-sizing: border-box to the second. Give each a different background colour. Use DevTools to confirm the content-box element is wider than 300px, while the border-box element is exactly 300px.
Hint: use display: inline-block or float: left to place the boxes side by side (or just stack them vertically — the comparison still works). Inspect each in DevTools and compare the rendered widths.
CSS
.content-box-demo { box-sizing: content-box; width: 300px; padding: 20px; border: 4px solid #f08080; background-color: #2e1a1a; margin-bottom: 16px; color: #f08080; font-family: system-ui, sans-serif; } .border-box-demo { box-sizing: border-box; width: 300px; padding: 20px; border: 4px solid #7ecfa0; background-color: #1a2e1a; color: #7ecfa0; font-family: system-ui, sans-serif; }
HTML
<div class="content-box-demo">content-box: set 300px, renders as 348px</div> <div class="border-box-demo">border-box: set 300px, renders as 300px</div>

The content-box element renders at 348px (300 + 20 + 20 padding + 4 + 4 border). The border-box element is exactly 300px. Same CSS width, very different result — this is why the reset matters.