The Four Layers of the Box Model
Every element is surrounded by four layers, from inside to outside:
- Content — the actual text, image, or child elements
- Padding — transparent space between content and border
- Border — a line (visible or invisible) around the padding
- Margin — transparent space outside the border, separating from other elements
Content Box – width and height
width and height set the size of the content area by default (in content-box mode).
.card {
width: 300px;
height: 200px;
}
/* Min and max constraints */
.container {
width: 100%;
max-width: 1200px; /* won't grow wider than 1200px */
min-width: 320px; /* won't shrink below 320px */
}
.hero {
height: 100vh; /* full viewport height */
min-height: 400px; /* minimum on small screens */
}
/* Intrinsic sizing keywords */
.inline { width: fit-content; } /* shrinks to content */
.full { width: stretch; } /* fills available space */
Padding – Inner Breathing Room
Padding is the space between the content and the border. Background color and background images extend into the padding area.
/* Longhand — individual sides */
padding-top: 16px;
padding-right: 24px;
padding-bottom: 16px;
padding-left: 24px;
/* Shorthand: top | right | bottom | left (clockwise) */
padding: 16px 24px 16px 24px;
/* Shorthand: top/bottom | left/right */
padding: 16px 24px;
/* Shorthand: all four equal */
padding: 16px;
/* Shorthand: top | left/right | bottom */
padding: 8px 16px 24px;
/* Percentage — relative to the element's WIDTH (both axes!) */
padding: 5%; /* 5% of the element's own width */
/* Common patterns */
.btn { padding: 10px 24px; } /* horizontal buttons */
.card { padding: 24px; } /* even card padding */
.section { padding: 80px 0; } /* top/bottom sections, no horizontal */
Background color fills the content box and the padding. Margin is always transparent — it only creates space between elements. If you want a colored gap between content and border, use padding. If you want invisible space between elements, use margin.
Border – The Line Around the Box
Border sits between padding and margin. A border of 0 width still exists in the box model — it just has no visible thickness.
/* Shorthand: width style color */
border: 1px solid #ccc;
border: 2px solid #1572B6;
border: 3px dashed #e63946;
border: 4px double navy;
border: none;
/* Individual sides */
border-top: 2px solid #1572B6;
border-right: none;
border-bottom: 1px solid #eee;
border-left: 4px solid #1572B6; /* left accent border */
/* Longhand properties */
border-width: 2px;
border-style: solid; /* solid | dashed | dotted | double | groove | none */
border-color: #1572B6;
/* Rounded corners */
border-radius: 4px; /* same for all corners */
border-radius: 50%; /* circle (on equal width/height) */
border-radius: 12px 4px; /* top-left/bottom-right | top-right/bottom-left */
border-radius: 8px 8px 0 0; /* top-left | top-right | bottom-right | bottom-left */
/* Pill shape */
.badge { border-radius: 9999px; } /* always fully rounded */
Margin – Outer Spacing
Margin creates transparent space outside the border, between this element and its neighbors.
/* Same shorthand as padding */
margin: 16px;
margin: 16px 24px;
margin: 16px 24px 32px 24px;
/* Auto — center a block element horizontally */
.container {
width: 800px;
margin: 0 auto; /* top/bottom = 0, left/right = auto (equal) */
}
/* Negative margins — pull element closer or overlap */
.pull-up { margin-top: -20px; }
/* Remove default browser margins */
h1, h2, p, ul { margin: 0; }
/* Stack spacing — bottom margin on everything */
.content > * + * { margin-top: 1rem; } /* lobotomized owl — gap between children */
Margin Collapse
This is one of CSS's most surprising behaviors. Vertical margins between adjacent block elements collapse — they merge into a single margin equal to the larger of the two:
h2 { margin-bottom: 32px; }
p { margin-top: 16px; }
/* Gap between h2 and p = 32px (larger wins), NOT 32+16=48px */
Margin collapse only happens with vertical margins (top/bottom). Horizontal margins (left/right) never collapse. It also doesn't happen with flexbox or grid children.
box-sizing – The Most Important Reset
By default (box-sizing: content-box), when you set width: 300px, that is the width of the content only. Adding padding: 20px and border: 2px makes the total rendered width 300 + 40 + 4 = 344px.
box-sizing: border-box changes this: the width you set becomes the total rendered width — padding and border are subtracted from the inside.
/* Default: content-box */
.box {
width: 300px;
padding: 20px;
border: 2px solid black;
/* Rendered width = 300 + 40 + 4 = 344px — WIDER THAN EXPECTED */
}
/* border-box: width INCLUDES padding and border */
.box {
box-sizing: border-box;
width: 300px;
padding: 20px;
border: 2px solid black;
/* Rendered width = 300px — as expected */
/* Content area = 300 - 40 - 4 = 256px */
}
/* Apply to everything — the standard CSS reset */
*, *::before, *::after {
box-sizing: border-box;
}
Put *, *::before, *::after { box-sizing: border-box; } at the top of every stylesheet. It prevents almost all sizing arithmetic bugs and is the standard approach used by Bootstrap, Tailwind, and virtually every modern CSS framework. Without it, any width: 100% element with padding will overflow its container.
Inspecting the Box Model in DevTools
Every browser's DevTools shows the box model visually:
- Right-click any element → Inspect
- In the Elements panel, look for the "Computed" tab
- You will see an interactive box model diagram showing the exact pixel values for content, padding, border, and margin
- Hover each layer in the diagram to highlight it on the page
This is invaluable for debugging spacing issues — always check DevTools first before guessing at values.
📋 Summary
- Every element = rectangular box with four layers: content → padding → border → margin
- Padding — space inside the border. Background color fills padding. Use for inner breathing room.
- Border — line between padding and margin. Shorthand:
width style color.border-radiusfor rounded corners. - Margin — space outside the border. Always transparent.
margin: 0 autocenters blocks. - Margin collapse — adjacent vertical margins merge into the larger value. Horizontal margins never collapse.
- box-sizing: border-box — width/height include padding and border. Use this always via universal reset.
- Inspect box model live in browser DevTools → Elements → Computed tab.
Frequently Asked Questions
Padding is the space inside an element — between the content and the border. It's part of the element's clickable/touchable area and its background fills the padding. Margin is space outside the element — between its border and adjacent elements. Margin is always transparent and doesn't take a background. Rule of thumb: padding for inner breathing room (around content), margin for outer gap (between elements).
You're using box-sizing: content-box (the default). When you set width: 100% and add padding: 20px, the total rendered width becomes 100% + 40px — wider than the container, causing overflow. Fix: add *, *::before, *::after { box-sizing: border-box; } to your stylesheet. With border-box, padding and border are included in the 100%, not added on top.
Margin collapse is when the bottom margin of one element and the top margin of the next merge into a single margin equal to the larger value. To prevent it: (1) use display: flex or display: grid on the parent — flex/grid children don't collapse. (2) Add padding: 1px or border: 1px solid transparent to the parent. (3) Use the gap property in flex/grid instead of margins. In most modern CSS, flexbox/grid is used for layout and margin collapse becomes a non-issue.
Not automatically — you must declare it. The universal reset (*, *::before, *::after { box-sizing: border-box; }) applies it to all elements and is the industry standard. It's included in Bootstrap, Tailwind, and most CSS resets. Setting it on a parent does NOT inherit it to children because box-sizing is a non-inheriting property — that's why the universal * selector is necessary rather than just setting it on html.