CSS Box Model Explained: Margin, Padding, and Border
Understand the CSS box model and how margin, padding, border, and content work together.
What Is the CSS Box Model?
Every element you render in a browser is a rectangular box. The CSS box model defines how that box is structured and how its dimensions are calculated. Until you truly understand this model, you'll constantly fight layouts that don't behave the way you expect — elements overflowing their containers, spacing that looks wrong, or widths that refuse to add up correctly.
The box model consists of four layers, from the inside out:
- Content — where your text, images, or child elements live
- Padding — transparent space between the content and the border
- Border — a visible (or invisible) frame around the padding
- Margin — transparent space outside the border, separating this element from others
Here's a quick visual reference:
+---------------------------+
| MARGIN |
| +---------------------+ |
| | BORDER | |
| | +--------------+ | |
| | | PADDING | | |
| | | +--------+ | | |
| | | | CONTENT| | | |
| | | +--------+ | | |
| | +--------------+ | |
| +---------------------+ |
+---------------------------+
The Default Sizing Problem: content-box
By default, browsers use box-sizing: content-box. This means when you set width: 300px, you're only setting the content area width. Any padding and border you add gets stacked on top of that, making the element wider than you declared.
.box {
width: 300px;
padding: 20px;
border: 5px solid #333;
/* box-sizing: content-box (default) */
}
The actual rendered width of .box here is:
300px (content)
+ 20px (padding-left) + 20px (padding-right)
+ 5px (border-left) + 5px (border-right)
= 350px total
You asked for 300px, you got 350px. This surprises almost every developer at least once.
The Fix: box-sizing: border-box
Switching to box-sizing: border-box changes the calculation so that width and height include padding and border. The content area shrinks to accommodate them, but the outer dimensions match exactly what you specified.
.box {
width: 300px;
padding: 20px;
border: 5px solid #333;
box-sizing: border-box;
/* Total rendered width: exactly 300px */
/* Content area: 300 - 40 - 10 = 250px */
}
The best practice is to apply this globally from the start of every project:
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
This single reset prevents most box model headaches before they start. It works reliably in every browser in use today, and it makes Flexbox and Grid layouts far more predictable.
Understanding Margin, Padding, and Border in Detail
Padding
Padding is the space between your content and its border. It's transparent but inherits the element's background color, which is why increasing padding makes a colored box appear bigger — the background fills the padded area.
.card {
padding: 24px; /* all four sides */
padding: 16px 24px; /* top/bottom | left/right */
padding: 8px 16px 24px 32px; /* top | right | bottom | left */
/* Logical properties (preferred for i18n) */
padding-block: 16px; /* top and bottom */
padding-inline: 24px; /* left and right */
}
Avoid using padding to create spacing between separate elements — that's what margin is for.
Border
A border requires three values to be visible: width, style, and color. The style is the one developers most often forget, which results in an invisible border.
.box {
border: 2px solid #e2e8f0; /* shorthand */
border-top: 4px solid #3b82f6; /* single side */
border-radius: 8px; /* rounds corners */
/* Individual properties */
border-width: 2px;
border-style: solid; /* dashed, dotted, double, none */
border-color: #e2e8f0;
}
Need to experiment with rounded corners visually? Use the border-radius generator to dial in the exact values without trial and error.
Margin
Margin controls the space outside the border. Unlike padding, margin doesn't inherit background — it's always transparent. Use margin: auto on block elements to center them horizontally inside their container.
.container {
width: 800px;
margin: 0 auto; /* centers the element horizontally */
}
.section {
margin-top: 48px;
margin-bottom: 32px;
/* Logical property equivalent */
margin-block: 32px 48px;
}
Margin Collapse
One of the most misunderstood behaviors in CSS is margin collapse. When two block elements stack vertically, their adjacent margins don't add up — the larger margin wins and the smaller one disappears.
.heading {
margin-bottom: 32px;
}
.paragraph {
margin-top: 16px;
}
/* The space between them is 32px, not 48px */
Margin collapse only happens vertically (between top and bottom margins). It doesn't occur horizontally, on floated elements, or inside flex/grid containers. When you're inside a flex or grid layout, you can forget about collapse entirely and use gap for spacing instead.
A Complete Practical Example
Here's a real-world card component that demonstrates all four box model layers working together:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: system-ui, sans-serif;
background: #f1f5f9;
padding: 40px;
}
.card {
width: 100%;
max-width: 360px;
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.card__image {
width: 100%;
height: 200px;
object-fit: cover;
display: block; /* removes inline gap below image */
}
.card__body {
padding: 24px; /* padding adds space inside, within 360px */
}
.card__title {
font-size: 1.25rem;
font-weight: 700;
color: #1e293b;
margin-bottom: 8px;
}
.card__text {
font-size: 0.9375rem;
color: #64748b;
line-height: 1.6;
margin-bottom: 20px;
}
.card__btn {
display: block;
width: 100%;
padding: 12px 24px;
background: #3b82f6;
color: #fff;
font-size: 1rem;
font-weight: 600;
border: none;
border-radius: 8px;
cursor: pointer;
text-align: center;
}
.card__btn:hover {
background: #2563eb;
}
</style>
</head>
<body>
<div class="card">
<img
class="card__image"
src="https://picsum.photos/360/200"
alt="Card cover"
>
<div class="card__body">
<h2 class="card__title">Card Component</h2>
<p class="card__text">
The total card width stays at 360px regardless of padding and
border, because we're using border-box sizing globally.
</p>
<button class="card__btn">Get Started</button>
</div>
</div>
</body>
</html>
The card width is always exactly 360px. The 24px padding inside .card__body doesn't inflate it — the content area shrinks instead. That's border-box doing exactly what you want. You can add depth and polish using box-shadow without affecting the layout at all. For more shadow options, check out the box-shadow generator.
Common Mistakes to Avoid
Mixing box-sizing values — If your global reset uses border-box but a third-party component overrides it back to content-box, you'll get inconsistent sizing. Keep an eye on specificity in your CSS.
Assuming margin always pushes elements apart — Adjacent vertical margins collapse. If you're debugging a gap that's smaller than expected, check if collapse is the cause.
Using padding to space sibling elements — Padding is internal spacing. For gaps between separate elements, use margin or, better yet, gap inside a flex or grid container.
Forgetting display: block on images — Inline images have a small gap beneath them caused by baseline alignment. Add display: block to remove it.
Applying padding to inline elements and expecting vertical spacing — Inline elements accept horizontal padding reliably, but vertical padding doesn't push surrounding lines apart. Convert to inline-block or block if you need vertical spacing.
Debugging the Box Model
When spacing looks off, open browser DevTools and inspect the element. The Computed panel shows a visual diagram of the exact margin, border, padding, and content measurements for any selected element. This is the fastest way to catch unexpected extra space or overflow.
If you're writing complex CSS and want to validate or clean up your rules quickly, run your stylesheet through the CSS formatter to catch syntax issues and improve readability.
Next Steps
Now that you understand the CSS box model, margin collapse, and the critical difference between content-box and border-box, you're ready to build more predictable layouts. Here's where to go next:
- Flexbox Guide — Learn how
display: flexchanges spacing behavior and whygapbeats margin for flex children - CSS Grid Layout — Apply box model knowledge to two-dimensional layouts with precise control over rows and columns
- CSS Specificity and the Cascade — Understand why your box model rules sometimes don't apply as expected
- Border Radius Generator — Create and preview rounded corners without writing CSS by hand
- Box Shadow Generator — Build layered shadow effects that add depth without impacting layout
- CSS Formatter — Clean up and validate your stylesheets as your codebase grows
Mastering the box model is one of those fundamentals that pays off immediately and keeps paying off every time you touch a layout.
Related Tools
Border Radius Generator
Create custom border radius values for all corners. Preview different shapes.
Box Shadow Generator
Create CSS box shadows with multiple layers. Adjust offset, blur, spread, and color.
CSS Formatter
Beautify and format CSS code with proper indentation and structure.
Flexbox Generator
Visual Flexbox layout builder with all flex properties. See changes in real-time.
Continue Learning
CSS Fundamentals: Styling Web Pages
Master CSS basics including selectors, properties, and the box model.
intermediateCSS Flexbox: Complete Layout Guide
Master Flexbox for creating flexible, responsive layouts with ease.
intermediateCSS Specificity: How the Cascade Really Works
Learn how CSS specificity and the cascade determine which styles apply to your elements.